aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/hd-audio/notes.rst2
-rw-r--r--include/sound/hda_register.h30
-rw-r--r--include/sound/hdaudio.h28
-rw-r--r--include/uapi/sound/asound.h4
-rw-r--r--include/uapi/sound/firewire.h10
-rw-r--r--sound/core/timer.c19
-rw-r--r--sound/drivers/vx/vx_core.c4
-rw-r--r--sound/firewire/Kconfig20
-rw-r--r--sound/firewire/Makefile2
-rw-r--r--sound/firewire/amdtp-stream-trace.h94
-rw-r--r--sound/firewire/amdtp-stream.c158
-rw-r--r--sound/firewire/amdtp-stream.h16
-rw-r--r--sound/firewire/bebob/bebob_command.c30
-rw-r--r--sound/firewire/digi00x/amdtp-dot.c55
-rw-r--r--sound/firewire/digi00x/digi00x-midi.c208
-rw-r--r--sound/firewire/digi00x/digi00x-transaction.c88
-rw-r--r--sound/firewire/digi00x/digi00x.c13
-rw-r--r--sound/firewire/digi00x/digi00x.h7
-rw-r--r--sound/firewire/fcp.c12
-rw-r--r--sound/firewire/fireface/Makefile3
-rw-r--r--sound/firewire/fireface/amdtp-ff.c155
-rw-r--r--sound/firewire/fireface/ff-hwdep.c191
-rw-r--r--sound/firewire/fireface/ff-midi.c131
-rw-r--r--sound/firewire/fireface/ff-pcm.c409
-rw-r--r--sound/firewire/fireface/ff-proc.c63
-rw-r--r--sound/firewire/fireface/ff-protocol-ff400.c371
-rw-r--r--sound/firewire/fireface/ff-stream.c282
-rw-r--r--sound/firewire/fireface/ff-transaction.c295
-rw-r--r--sound/firewire/fireface/ff.c209
-rw-r--r--sound/firewire/fireface/ff.h146
-rw-r--r--sound/firewire/lib.c141
-rw-r--r--sound/firewire/lib.h54
-rw-r--r--sound/firewire/motu/Makefile6
-rw-r--r--sound/firewire/motu/amdtp-motu-trace.h123
-rw-r--r--sound/firewire/motu/amdtp-motu.c427
-rw-r--r--sound/firewire/motu/motu-hwdep.c198
-rw-r--r--sound/firewire/motu/motu-midi.c169
-rw-r--r--sound/firewire/motu/motu-pcm.c398
-rw-r--r--sound/firewire/motu/motu-proc.c118
-rw-r--r--sound/firewire/motu/motu-protocol-v2.c237
-rw-r--r--sound/firewire/motu/motu-protocol-v3.c311
-rw-r--r--sound/firewire/motu/motu-stream.c381
-rw-r--r--sound/firewire/motu/motu-transaction.c137
-rw-r--r--sound/firewire/motu/motu.c264
-rw-r--r--sound/firewire/motu/motu.h161
-rw-r--r--sound/firewire/oxfw/oxfw-command.c12
-rw-r--r--sound/firewire/tascam/tascam-midi.c13
-rw-r--r--sound/firewire/tascam/tascam-transaction.c142
-rw-r--r--sound/firewire/tascam/tascam.h39
-rw-r--r--sound/hda/ext/hdac_ext_controller.c6
-rw-r--r--sound/hda/hdac_controller.c2
-rw-r--r--sound/hda/hdac_stream.c4
-rw-r--r--sound/isa/es1688/es1688_lib.c2
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c2
-rw-r--r--sound/pci/au88x0/au88x0_core.c3
-rw-r--r--sound/pci/au88x0/au88x0_eq.c6
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c2
-rw-r--r--sound/pci/aw2/aw2-alsa.c2
-rw-r--r--sound/pci/bt87x.c6
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c4
-rw-r--r--sound/pci/cmipci.c6
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c26
-rw-r--r--sound/pci/emu10k1/emu10k1x.c6
-rw-r--r--sound/pci/emu10k1/emumixer.c30
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/ens1370.c4
-rw-r--r--sound/pci/hda/hda_auto_parser.c1
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c9
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/hda_intel.c139
-rw-r--r--sound/pci/hda/patch_ca0132.c10
-rw-r--r--sound/pci/hda/patch_conexant.c81
-rw-r--r--sound/pci/hda/patch_hdmi.c29
-rw-r--r--sound/pci/hda/patch_realtek.c221
-rw-r--r--sound/pci/ice1712/delta.c2
-rw-r--r--sound/pci/ice1712/ews.c4
-rw-r--r--sound/pci/ice1712/ice1712.c30
-rw-r--r--sound/pci/ice1712/ice1724.c20
-rw-r--r--sound/pci/lola/lola_mixer.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c2
-rw-r--r--sound/pci/mixart/mixart_mixer.c6
-rw-r--r--sound/pci/oxygen/oxygen.c6
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c6
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c22
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/via82xx.c6
-rw-r--r--sound/pci/vx222/vx222_ops.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c14
-rw-r--r--sound/soc/intel/skylake/skl.h21
-rw-r--r--sound/synth/emux/emux_oss.c4
-rw-r--r--sound/usb/card.c6
-rw-r--r--sound/usb/line6/pcm.c2
-rw-r--r--sound/usb/line6/pod.c2
-rw-r--r--sound/usb/line6/toneport.c4
-rw-r--r--sound/usb/midi.c2
-rw-r--r--sound/usb/mixer.c6
-rw-r--r--sound/usb/mixer_scarlett.c12
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
104 files changed, 6475 insertions, 737 deletions
diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst
index 9eeb9b468706..f59c3cdbfaf4 100644
--- a/Documentation/sound/hd-audio/notes.rst
+++ b/Documentation/sound/hd-audio/notes.rst
@@ -494,6 +494,8 @@ add_hp_mic (bool)
494hp_mic_detect (bool) 494hp_mic_detect (bool)
495 enable/disable the hp/mic shared input for a single built-in mic 495 enable/disable the hp/mic shared input for a single built-in mic
496 case; default true 496 case; default true
497vmaster (bool)
498 enable/disable the virtual Master control; default true
497mixer_nid (int) 499mixer_nid (int)
498 specifies the widget NID of the analog-loopback mixer 500 specifies the widget NID of the analog-loopback mixer
499 501
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index 0013063db7f2..15fc6daf9096 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -106,8 +106,26 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
106#define AZX_REG_HSW_EM4 0x100c 106#define AZX_REG_HSW_EM4 0x100c
107#define AZX_REG_HSW_EM5 0x1010 107#define AZX_REG_HSW_EM5 0x1010
108 108
109/* Skylake/Broxton display HD-A controller Extended Mode registers */ 109/* Skylake/Broxton vendor-specific registers */
110#define AZX_REG_SKL_EM4L 0x1040 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
111 129
112/* PCI space */ 130/* PCI space */
113#define AZX_PCIREG_TCSEL 0x44 131#define AZX_PCIREG_TCSEL 0x44
@@ -243,9 +261,11 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
243#define AZX_REG_ML_LOUTPAY 0x20 261#define AZX_REG_ML_LOUTPAY 0x20
244#define AZX_REG_ML_LINPAY 0x30 262#define AZX_REG_ML_LINPAY 0x30
245 263
246#define AZX_MLCTL_SPA (1<<16) 264#define ML_LCTL_SCF_MASK 0xF
247#define AZX_MLCTL_CPA 23 265#define AZX_MLCTL_SPA (0x1 << 16)
248 266#define AZX_MLCTL_CPA (0x1 << 23)
267#define AZX_MLCTL_SPA_SHIFT 16
268#define AZX_MLCTL_CPA_SHIFT 23
249 269
250/* registers for DMA Resume Capability Structure */ 270/* registers for DMA Resume Capability Structure */
251#define AZX_DRSM_CAP_ID 0x5 271#define AZX_DRSM_CAP_ID 0x5
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 56004ec8d441..96546b30e900 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -368,24 +368,32 @@ void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
368/* 368/*
369 * macros for easy use 369 * macros for easy use
370 */ 370 */
371#define _snd_hdac_chip_write(type, chip, reg, value) \ 371#define _snd_hdac_chip_writeb(chip, reg, value) \
372 ((chip)->io_ops->reg_write ## type(value, (chip)->remap_addr + (reg))) 372 ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg)))
373#define _snd_hdac_chip_read(type, chip, reg) \ 373#define _snd_hdac_chip_readb(chip, reg) \
374 ((chip)->io_ops->reg_read ## type((chip)->remap_addr + (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)))
375 383
376/* read/write a register, pass without AZX_REG_ prefix */ 384/* read/write a register, pass without AZX_REG_ prefix */
377#define snd_hdac_chip_writel(chip, reg, value) \ 385#define snd_hdac_chip_writel(chip, reg, value) \
378 _snd_hdac_chip_write(l, chip, AZX_REG_ ## reg, value) 386 _snd_hdac_chip_writel(chip, AZX_REG_ ## reg, value)
379#define snd_hdac_chip_writew(chip, reg, value) \ 387#define snd_hdac_chip_writew(chip, reg, value) \
380 _snd_hdac_chip_write(w, chip, AZX_REG_ ## reg, value) 388 _snd_hdac_chip_writew(chip, AZX_REG_ ## reg, value)
381#define snd_hdac_chip_writeb(chip, reg, value) \ 389#define snd_hdac_chip_writeb(chip, reg, value) \
382 _snd_hdac_chip_write(b, chip, AZX_REG_ ## reg, value) 390 _snd_hdac_chip_writeb(chip, AZX_REG_ ## reg, value)
383#define snd_hdac_chip_readl(chip, reg) \ 391#define snd_hdac_chip_readl(chip, reg) \
384 _snd_hdac_chip_read(l, chip, AZX_REG_ ## reg) 392 _snd_hdac_chip_readl(chip, AZX_REG_ ## reg)
385#define snd_hdac_chip_readw(chip, reg) \ 393#define snd_hdac_chip_readw(chip, reg) \
386 _snd_hdac_chip_read(w, chip, AZX_REG_ ## reg) 394 _snd_hdac_chip_readw(chip, AZX_REG_ ## reg)
387#define snd_hdac_chip_readb(chip, reg) \ 395#define snd_hdac_chip_readb(chip, reg) \
388 _snd_hdac_chip_read(b, chip, AZX_REG_ ## reg) 396 _snd_hdac_chip_readb(chip, AZX_REG_ ## reg)
389 397
390/* update a register, pass without AZX_REG_ prefix */ 398/* update a register, pass without AZX_REG_ prefix */
391#define snd_hdac_chip_updatel(chip, reg, mask, val) \ 399#define snd_hdac_chip_updatel(chip, reg, mask, val) \
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index be353a78c303..fd41697cb4d3 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -107,9 +107,11 @@ enum {
107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ 107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */
108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ 108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */
109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ 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 */
110 112
111 /* Don't forget to change the following: */ 113 /* Don't forget to change the following: */
112 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6 114 SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
113}; 115};
114 116
115struct snd_hwdep_info { 117struct snd_hwdep_info {
diff --git a/include/uapi/sound/firewire.h b/include/uapi/sound/firewire.h
index db79a12fcc78..622900488bdc 100644
--- a/include/uapi/sound/firewire.h
+++ b/include/uapi/sound/firewire.h
@@ -10,6 +10,7 @@
10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e 10#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 11#define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475
12#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c 12#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
13#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
13 14
14struct snd_firewire_event_common { 15struct snd_firewire_event_common {
15 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ 16 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
@@ -46,12 +47,18 @@ struct snd_firewire_event_digi00x_message {
46 __u32 message; /* Digi00x-specific message */ 47 __u32 message; /* Digi00x-specific message */
47}; 48};
48 49
50struct snd_firewire_event_motu_notification {
51 unsigned int type;
52 __u32 message; /* MOTU-specific bits. */
53};
54
49union snd_firewire_event { 55union snd_firewire_event {
50 struct snd_firewire_event_common common; 56 struct snd_firewire_event_common common;
51 struct snd_firewire_event_lock_status lock_status; 57 struct snd_firewire_event_lock_status lock_status;
52 struct snd_firewire_event_dice_notification dice_notification; 58 struct snd_firewire_event_dice_notification dice_notification;
53 struct snd_firewire_event_efw_response efw_response; 59 struct snd_firewire_event_efw_response efw_response;
54 struct snd_firewire_event_digi00x_message digi00x_message; 60 struct snd_firewire_event_digi00x_message digi00x_message;
61 struct snd_firewire_event_motu_notification motu_notification;
55}; 62};
56 63
57 64
@@ -65,7 +72,8 @@ union snd_firewire_event {
65#define SNDRV_FIREWIRE_TYPE_OXFW 4 72#define SNDRV_FIREWIRE_TYPE_OXFW 4
66#define SNDRV_FIREWIRE_TYPE_DIGI00X 5 73#define SNDRV_FIREWIRE_TYPE_DIGI00X 5
67#define SNDRV_FIREWIRE_TYPE_TASCAM 6 74#define SNDRV_FIREWIRE_TYPE_TASCAM 6
68/* RME, MOTU, ... */ 75#define SNDRV_FIREWIRE_TYPE_MOTU 7
76#define SNDRV_FIREWIRE_TYPE_FIREFACE 8
69 77
70struct snd_firewire_get_info { 78struct snd_firewire_get_info {
71 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */ 79 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6d4fbc439246..2f836ca09860 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1277,6 +1277,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1277 struct timespec tstamp; 1277 struct timespec tstamp;
1278 int prev, append = 0; 1278 int prev, append = 0;
1279 1279
1280 memset(&r1, 0, sizeof(r1));
1280 memset(&tstamp, 0, sizeof(tstamp)); 1281 memset(&tstamp, 0, sizeof(tstamp));
1281 spin_lock(&tu->qlock); 1282 spin_lock(&tu->qlock);
1282 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | 1283 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
@@ -1292,7 +1293,6 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1292 } 1293 }
1293 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1294 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1294 tu->last_resolution != resolution) { 1295 tu->last_resolution != resolution) {
1295 memset(&r1, 0, sizeof(r1));
1296 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1296 r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
1297 r1.tstamp = tstamp; 1297 r1.tstamp = tstamp;
1298 r1.val = resolution; 1298 r1.val = resolution;
@@ -1430,18 +1430,13 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1430 if (id.card < 0) { 1430 if (id.card < 0) {
1431 id.card = 0; 1431 id.card = 0;
1432 } else { 1432 } else {
1433 if (id.card < 0) { 1433 if (id.device < 0) {
1434 id.card = 0; 1434 id.device = 0;
1435 } else { 1435 } else {
1436 if (id.device < 0) { 1436 if (id.subdevice < 0)
1437 id.device = 0; 1437 id.subdevice = 0;
1438 } else { 1438 else
1439 if (id.subdevice < 0) { 1439 id.subdevice++;
1440 id.subdevice = 0;
1441 } else {
1442 id.subdevice++;
1443 }
1444 }
1445 } 1440 }
1446 } 1441 }
1447 list_for_each(p, &snd_timer_list) { 1442 list_for_each(p, &snd_timer_list) {
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 289f041706cd..f684fffd1397 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -795,10 +795,8 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
795 return NULL; 795 return NULL;
796 796
797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL); 797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
798 if (! chip) { 798 if (! chip)
799 snd_printk(KERN_ERR "vx_core: no memory\n");
800 return NULL; 799 return NULL;
801 }
802 mutex_init(&chip->lock); 800 mutex_init(&chip->lock);
803 chip->irq = -1; 801 chip->irq = -1;
804 chip->hw = hw; 802 chip->hw = hw;
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 9f00696c4e4a..529d9f405fa9 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -140,4 +140,24 @@ config SND_FIREWIRE_TASCAM
140 To compile this driver as a module, choose M here: the module 140 To compile this driver as a module, choose M here: the module
141 will be called snd-firewire-tascam. 141 will be called snd-firewire-tascam.
142 142
143config 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
155config 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
143endif # SND_FIREWIRE 163endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 0ee1fb115d88..1b98fa3fa3d4 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_SND_FIREWORKS) += fireworks/
13obj-$(CONFIG_SND_BEBOB) += bebob/ 13obj-$(CONFIG_SND_BEBOB) += bebob/
14obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/ 14obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/
15obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/ 15obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/
16obj-$(CONFIG_SND_FIREWIRE_MOTU) += motu/
17obj-$(CONFIG_SND_FIREFACE) += fireface/
diff --git a/sound/firewire/amdtp-stream-trace.h b/sound/firewire/amdtp-stream-trace.h
index 9c04faf206b2..ea0d486652c8 100644
--- a/sound/firewire/amdtp-stream-trace.h
+++ b/sound/firewire/amdtp-stream-trace.h
@@ -14,8 +14,8 @@
14#include <linux/tracepoint.h> 14#include <linux/tracepoint.h>
15 15
16TRACE_EVENT(in_packet, 16TRACE_EVENT(in_packet,
17 TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_quadlets, unsigned int index), 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_quadlets, index), 18 TP_ARGS(s, cycles, cip_header, payload_length, index),
19 TP_STRUCT__entry( 19 TP_STRUCT__entry(
20 __field(unsigned int, second) 20 __field(unsigned int, second)
21 __field(unsigned int, cycle) 21 __field(unsigned int, cycle)
@@ -37,7 +37,7 @@ TRACE_EVENT(in_packet,
37 __entry->dest = fw_parent_device(s->unit)->card->node_id; 37 __entry->dest = fw_parent_device(s->unit)->card->node_id;
38 __entry->cip_header0 = cip_header[0]; 38 __entry->cip_header0 = cip_header[0];
39 __entry->cip_header1 = cip_header[1]; 39 __entry->cip_header1 = cip_header[1];
40 __entry->payload_quadlets = payload_quadlets; 40 __entry->payload_quadlets = payload_length / 4;
41 __entry->packet_index = s->packet_index; 41 __entry->packet_index = s->packet_index;
42 __entry->irq = !!in_interrupt(); 42 __entry->irq = !!in_interrupt();
43 __entry->index = index; 43 __entry->index = index;
@@ -101,6 +101,94 @@ TRACE_EVENT(out_packet,
101 __entry->index) 101 __entry->index)
102); 102);
103 103
104TRACE_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
148TRACE_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)
190);
191
104#endif 192#endif
105 193
106#undef TRACE_INCLUDE_PATH 194#undef TRACE_INCLUDE_PATH
diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 00060c4a9deb..9e6f54f8c45d 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -27,6 +27,7 @@
27 27
28/* isochronous header parameters */ 28/* isochronous header parameters */
29#define ISO_DATA_LENGTH_SHIFT 16 29#define ISO_DATA_LENGTH_SHIFT 16
30#define TAG_NO_CIP_HEADER 0
30#define TAG_CIP 1 31#define TAG_CIP 1
31 32
32/* common isochronous packet header parameters */ 33/* common isochronous packet header parameters */
@@ -37,6 +38,8 @@
37#define CIP_SID_MASK 0x3f000000 38#define CIP_SID_MASK 0x3f000000
38#define CIP_DBS_MASK 0x00ff0000 39#define CIP_DBS_MASK 0x00ff0000
39#define CIP_DBS_SHIFT 16 40#define CIP_DBS_SHIFT 16
41#define CIP_SPH_MASK 0x00000400
42#define CIP_SPH_SHIFT 10
40#define CIP_DBC_MASK 0x000000ff 43#define CIP_DBC_MASK 0x000000ff
41#define CIP_FMT_SHIFT 24 44#define CIP_FMT_SHIFT 24
42#define CIP_FMT_MASK 0x3f000000 45#define CIP_FMT_MASK 0x3f000000
@@ -232,11 +235,15 @@ EXPORT_SYMBOL(amdtp_stream_set_parameters);
232unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 235unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)
233{ 236{
234 unsigned int multiplier = 1; 237 unsigned int multiplier = 1;
238 unsigned int header_size = 0;
235 239
236 if (s->flags & CIP_JUMBO_PAYLOAD) 240 if (s->flags & CIP_JUMBO_PAYLOAD)
237 multiplier = 5; 241 multiplier = 5;
242 if (!(s->flags & CIP_NO_HEADER))
243 header_size = 8;
238 244
239 return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier; 245 return header_size +
246 s->syt_interval * s->data_block_quadlets * 4 * multiplier;
240} 247}
241EXPORT_SYMBOL(amdtp_stream_get_max_payload); 248EXPORT_SYMBOL(amdtp_stream_get_max_payload);
242 249
@@ -378,7 +385,7 @@ static int queue_packet(struct amdtp_stream *s, unsigned int header_length,
378 goto end; 385 goto end;
379 386
380 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL); 387 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);
381 p.tag = TAG_CIP; 388 p.tag = s->tag;
382 p.header_length = header_length; 389 p.header_length = header_length;
383 if (payload_length > 0) 390 if (payload_length > 0)
384 p.payload_length = payload_length; 391 p.payload_length = payload_length;
@@ -405,17 +412,16 @@ static inline int queue_out_packet(struct amdtp_stream *s,
405 412
406static inline int queue_in_packet(struct amdtp_stream *s) 413static inline int queue_in_packet(struct amdtp_stream *s)
407{ 414{
408 return queue_packet(s, IN_PACKET_HEADER_SIZE, 415 return queue_packet(s, IN_PACKET_HEADER_SIZE, s->max_payload_length);
409 amdtp_stream_get_max_payload(s));
410} 416}
411 417
412static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle, 418static int handle_out_packet(struct amdtp_stream *s,
419 unsigned int payload_length, unsigned int cycle,
413 unsigned int index) 420 unsigned int index)
414{ 421{
415 __be32 *buffer; 422 __be32 *buffer;
416 unsigned int syt; 423 unsigned int syt;
417 unsigned int data_blocks; 424 unsigned int data_blocks;
418 unsigned int payload_length;
419 unsigned int pcm_frames; 425 unsigned int pcm_frames;
420 struct snd_pcm_substream *pcm; 426 struct snd_pcm_substream *pcm;
421 427
@@ -424,15 +430,22 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,
424 data_blocks = calculate_data_blocks(s, syt); 430 data_blocks = calculate_data_blocks(s, syt);
425 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt); 431 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);
426 432
433 if (s->flags & CIP_DBC_IS_END_EVENT)
434 s->data_block_counter =
435 (s->data_block_counter + data_blocks) & 0xff;
436
427 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | 437 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
428 (s->data_block_quadlets << CIP_DBS_SHIFT) | 438 (s->data_block_quadlets << CIP_DBS_SHIFT) |
439 ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) |
429 s->data_block_counter); 440 s->data_block_counter);
430 buffer[1] = cpu_to_be32(CIP_EOH | 441 buffer[1] = cpu_to_be32(CIP_EOH |
431 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) | 442 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
432 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) | 443 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
433 (syt & CIP_SYT_MASK)); 444 (syt & CIP_SYT_MASK));
434 445
435 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; 446 if (!(s->flags & CIP_DBC_IS_END_EVENT))
447 s->data_block_counter =
448 (s->data_block_counter + data_blocks) & 0xff;
436 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; 449 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
437 450
438 trace_out_packet(s, cycle, buffer, payload_length, index); 451 trace_out_packet(s, cycle, buffer, payload_length, index);
@@ -448,13 +461,45 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,
448 return 0; 461 return 0;
449} 462}
450 463
464static int handle_out_packet_without_header(struct amdtp_stream *s,
465 unsigned int payload_length, unsigned int cycle,
466 unsigned int index)
467{
468 __be32 *buffer;
469 unsigned int syt;
470 unsigned int data_blocks;
471 unsigned int pcm_frames;
472 struct snd_pcm_substream *pcm;
473
474 buffer = s->buffer.packets[s->packet_index].buffer;
475 syt = calculate_syt(s, cycle);
476 data_blocks = calculate_data_blocks(s, syt);
477 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt);
478 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
479
480 payload_length = data_blocks * 4 * s->data_block_quadlets;
481
482 trace_out_packet_without_header(s, cycle, payload_length, data_blocks,
483 index);
484
485 if (queue_out_packet(s, payload_length) < 0)
486 return -EIO;
487
488 pcm = ACCESS_ONCE(s->pcm);
489 if (pcm && pcm_frames > 0)
490 update_pcm_pointers(s, pcm, pcm_frames);
491
492 /* No need to return the number of handled data blocks. */
493 return 0;
494}
495
451static int handle_in_packet(struct amdtp_stream *s, 496static int handle_in_packet(struct amdtp_stream *s,
452 unsigned int payload_quadlets, unsigned int cycle, 497 unsigned int payload_length, unsigned int cycle,
453 unsigned int index) 498 unsigned int index)
454{ 499{
455 __be32 *buffer; 500 __be32 *buffer;
456 u32 cip_header[2]; 501 u32 cip_header[2];
457 unsigned int fmt, fdf, syt; 502 unsigned int sph, fmt, fdf, syt;
458 unsigned int data_block_quadlets, data_block_counter, dbc_interval; 503 unsigned int data_block_quadlets, data_block_counter, dbc_interval;
459 unsigned int data_blocks; 504 unsigned int data_blocks;
460 struct snd_pcm_substream *pcm; 505 struct snd_pcm_substream *pcm;
@@ -465,14 +510,15 @@ static int handle_in_packet(struct amdtp_stream *s,
465 cip_header[0] = be32_to_cpu(buffer[0]); 510 cip_header[0] = be32_to_cpu(buffer[0]);
466 cip_header[1] = be32_to_cpu(buffer[1]); 511 cip_header[1] = be32_to_cpu(buffer[1]);
467 512
468 trace_in_packet(s, cycle, cip_header, payload_quadlets, index); 513 trace_in_packet(s, cycle, cip_header, payload_length, index);
469 514
470 /* 515 /*
471 * This module supports 'Two-quadlet CIP header with SYT field'. 516 * This module supports 'Two-quadlet CIP header with SYT field'.
472 * For convenience, also check FMT field is AM824 or not. 517 * For convenience, also check FMT field is AM824 or not.
473 */ 518 */
474 if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) || 519 if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||
475 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) { 520 ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) &&
521 (!(s->flags & CIP_HEADER_WITHOUT_EOH))) {
476 dev_info_ratelimited(&s->unit->device, 522 dev_info_ratelimited(&s->unit->device,
477 "Invalid CIP header for AMDTP: %08X:%08X\n", 523 "Invalid CIP header for AMDTP: %08X:%08X\n",
478 cip_header[0], cip_header[1]); 524 cip_header[0], cip_header[1]);
@@ -482,8 +528,9 @@ static int handle_in_packet(struct amdtp_stream *s,
482 } 528 }
483 529
484 /* Check valid protocol or not. */ 530 /* Check valid protocol or not. */
531 sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT;
485 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT; 532 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;
486 if (fmt != s->fmt) { 533 if (sph != s->sph || fmt != s->fmt) {
487 dev_info_ratelimited(&s->unit->device, 534 dev_info_ratelimited(&s->unit->device,
488 "Detect unexpected protocol: %08x %08x\n", 535 "Detect unexpected protocol: %08x %08x\n",
489 cip_header[0], cip_header[1]); 536 cip_header[0], cip_header[1]);
@@ -494,7 +541,7 @@ static int handle_in_packet(struct amdtp_stream *s,
494 541
495 /* Calculate data blocks */ 542 /* Calculate data blocks */
496 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT; 543 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;
497 if (payload_quadlets < 3 || 544 if (payload_length < 12 ||
498 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) { 545 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {
499 data_blocks = 0; 546 data_blocks = 0;
500 } else { 547 } else {
@@ -510,7 +557,8 @@ static int handle_in_packet(struct amdtp_stream *s,
510 if (s->flags & CIP_WRONG_DBS) 557 if (s->flags & CIP_WRONG_DBS)
511 data_block_quadlets = s->data_block_quadlets; 558 data_block_quadlets = s->data_block_quadlets;
512 559
513 data_blocks = (payload_quadlets - 2) / data_block_quadlets; 560 data_blocks = (payload_length / 4 - 2) /
561 data_block_quadlets;
514 } 562 }
515 563
516 /* Check data block counter continuity */ 564 /* Check data block counter continuity */
@@ -561,6 +609,34 @@ end:
561 return 0; 609 return 0;
562} 610}
563 611
612static int handle_in_packet_without_header(struct amdtp_stream *s,
613 unsigned int payload_quadlets, unsigned int cycle,
614 unsigned int index)
615{
616 __be32 *buffer;
617 unsigned int data_blocks;
618 struct snd_pcm_substream *pcm;
619 unsigned int pcm_frames;
620
621 buffer = s->buffer.packets[s->packet_index].buffer;
622 data_blocks = payload_quadlets / s->data_block_quadlets;
623
624 trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks,
625 index);
626
627 pcm_frames = s->process_data_blocks(s, buffer, data_blocks, NULL);
628 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
629
630 if (queue_in_packet(s) < 0)
631 return -EIO;
632
633 pcm = ACCESS_ONCE(s->pcm);
634 if (pcm && pcm_frames > 0)
635 update_pcm_pointers(s, pcm, pcm_frames);
636
637 return 0;
638}
639
564/* 640/*
565 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On 641 * In CYCLE_TIMER register of IEEE 1394, 7 bits are used to represent second. On
566 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent 642 * the other hand, in DMA descriptors of 1394 OHCI, 3 bits are used to represent
@@ -604,7 +680,7 @@ static void out_stream_callback(struct fw_iso_context *context, u32 tstamp,
604 680
605 for (i = 0; i < packets; ++i) { 681 for (i = 0; i < packets; ++i) {
606 cycle = increment_cycle_count(cycle, 1); 682 cycle = increment_cycle_count(cycle, 1);
607 if (handle_out_packet(s, cycle, i) < 0) { 683 if (s->handle_packet(s, 0, cycle, i) < 0) {
608 s->packet_index = -1; 684 s->packet_index = -1;
609 amdtp_stream_pcm_abort(s); 685 amdtp_stream_pcm_abort(s);
610 return; 686 return;
@@ -620,7 +696,7 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
620{ 696{
621 struct amdtp_stream *s = private_data; 697 struct amdtp_stream *s = private_data;
622 unsigned int i, packets; 698 unsigned int i, packets;
623 unsigned int payload_quadlets, max_payload_quadlets; 699 unsigned int payload_length, max_payload_length;
624 __be32 *headers = header; 700 __be32 *headers = header;
625 u32 cycle; 701 u32 cycle;
626 702
@@ -636,22 +712,22 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
636 cycle = decrement_cycle_count(cycle, packets); 712 cycle = decrement_cycle_count(cycle, packets);
637 713
638 /* For buffer-over-run prevention. */ 714 /* For buffer-over-run prevention. */
639 max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4; 715 max_payload_length = s->max_payload_length;
640 716
641 for (i = 0; i < packets; i++) { 717 for (i = 0; i < packets; i++) {
642 cycle = increment_cycle_count(cycle, 1); 718 cycle = increment_cycle_count(cycle, 1);
643 719
644 /* The number of quadlets in this packet */ 720 /* The number of bytes in this packet */
645 payload_quadlets = 721 payload_length =
646 (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT) / 4; 722 (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT);
647 if (payload_quadlets > max_payload_quadlets) { 723 if (payload_length > max_payload_length) {
648 dev_err(&s->unit->device, 724 dev_err(&s->unit->device,
649 "Detect jumbo payload: %02x %02x\n", 725 "Detect jumbo payload: %04x %04x\n",
650 payload_quadlets, max_payload_quadlets); 726 payload_length, max_payload_length);
651 break; 727 break;
652 } 728 }
653 729
654 if (handle_in_packet(s, payload_quadlets, cycle, i) < 0) 730 if (s->handle_packet(s, payload_length, cycle, i) < 0)
655 break; 731 break;
656 } 732 }
657 733
@@ -671,6 +747,10 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
671 void *header, void *private_data) 747 void *header, void *private_data)
672{ 748{
673 struct amdtp_stream *s = private_data; 749 struct amdtp_stream *s = private_data;
750 u32 cycle;
751 unsigned int packets;
752
753 s->max_payload_length = amdtp_stream_get_max_payload(s);
674 754
675 /* 755 /*
676 * For in-stream, first packet has come. 756 * For in-stream, first packet has come.
@@ -679,10 +759,27 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
679 s->callbacked = true; 759 s->callbacked = true;
680 wake_up(&s->callback_wait); 760 wake_up(&s->callback_wait);
681 761
682 if (s->direction == AMDTP_IN_STREAM) 762 cycle = compute_cycle_count(tstamp);
763
764 if (s->direction == AMDTP_IN_STREAM) {
765 packets = header_length / IN_PACKET_HEADER_SIZE;
766 cycle = decrement_cycle_count(cycle, packets);
683 context->callback.sc = in_stream_callback; 767 context->callback.sc = in_stream_callback;
684 else 768 if (s->flags & CIP_NO_HEADER)
769 s->handle_packet = handle_in_packet_without_header;
770 else
771 s->handle_packet = handle_in_packet;
772 } else {
773 packets = header_length / 4;
774 cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets);
685 context->callback.sc = out_stream_callback; 775 context->callback.sc = out_stream_callback;
776 if (s->flags & CIP_NO_HEADER)
777 s->handle_packet = handle_out_packet_without_header;
778 else
779 s->handle_packet = handle_out_packet;
780 }
781
782 s->start_cycle = cycle;
686 783
687 context->callback.sc(context, tstamp, header_length, header, s); 784 context->callback.sc(context, tstamp, header_length, header, s);
688} 785}
@@ -759,6 +856,11 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
759 856
760 amdtp_stream_update(s); 857 amdtp_stream_update(s);
761 858
859 if (s->flags & CIP_NO_HEADER)
860 s->tag = TAG_NO_CIP_HEADER;
861 else
862 s->tag = TAG_CIP;
863
762 s->packet_index = 0; 864 s->packet_index = 0;
763 do { 865 do {
764 if (s->direction == AMDTP_IN_STREAM) 866 if (s->direction == AMDTP_IN_STREAM)
@@ -771,7 +873,7 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
771 873
772 /* NOTE: TAG1 matches CIP. This just affects in stream. */ 874 /* NOTE: TAG1 matches CIP. This just affects in stream. */
773 tag = FW_ISO_CONTEXT_MATCH_TAG1; 875 tag = FW_ISO_CONTEXT_MATCH_TAG1;
774 if (s->flags & CIP_EMPTY_WITH_TAG0) 876 if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))
775 tag |= FW_ISO_CONTEXT_MATCH_TAG0; 877 tag |= FW_ISO_CONTEXT_MATCH_TAG0;
776 878
777 s->callbacked = false; 879 s->callbacked = false;
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index c1bc7fad056e..7e8831722821 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -18,8 +18,8 @@
18 * SYT_INTERVAL samples, with these two types alternating so that 18 * SYT_INTERVAL samples, with these two types alternating so that
19 * the overall sample rate comes out right. 19 * the overall sample rate comes out right.
20 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. 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 21 * @CIP_DBC_IS_END_EVENT: The value of dbc in an packet corresponds to the end
22 * corresponds to the end of event in the packet. Out of IEC 61883. 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. 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. 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 25 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is
@@ -29,6 +29,9 @@
29 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an 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 30 * packet is larger than IEC 61883-6 defines. Current implementation
31 * allows 5 times as large as IEC 61883-6 defines. 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
32 */ 35 */
33enum cip_flags { 36enum cip_flags {
34 CIP_NONBLOCKING = 0x00, 37 CIP_NONBLOCKING = 0x00,
@@ -39,6 +42,8 @@ enum cip_flags {
39 CIP_SKIP_DBC_ZERO_CHECK = 0x10, 42 CIP_SKIP_DBC_ZERO_CHECK = 0x10,
40 CIP_EMPTY_HAS_WRONG_DBC = 0x20, 43 CIP_EMPTY_HAS_WRONG_DBC = 0x20,
41 CIP_JUMBO_PAYLOAD = 0x40, 44 CIP_JUMBO_PAYLOAD = 0x40,
45 CIP_HEADER_WITHOUT_EOH = 0x80,
46 CIP_NO_HEADER = 0x100,
42}; 47};
43 48
44/** 49/**
@@ -101,11 +106,17 @@ struct amdtp_stream {
101 struct fw_iso_context *context; 106 struct fw_iso_context *context;
102 struct iso_packets_buffer buffer; 107 struct iso_packets_buffer buffer;
103 int packet_index; 108 int packet_index;
109 int tag;
110 int (*handle_packet)(struct amdtp_stream *s,
111 unsigned int payload_quadlets, unsigned int cycle,
112 unsigned int index);
113 unsigned int max_payload_length;
104 114
105 /* For CIP headers. */ 115 /* For CIP headers. */
106 unsigned int source_node_id_field; 116 unsigned int source_node_id_field;
107 unsigned int data_block_quadlets; 117 unsigned int data_block_quadlets;
108 unsigned int data_block_counter; 118 unsigned int data_block_counter;
119 unsigned int sph;
109 unsigned int fmt; 120 unsigned int fmt;
110 unsigned int fdf; 121 unsigned int fdf;
111 /* quirk: fixed interval of dbc between previos/current packets. */ 122 /* quirk: fixed interval of dbc between previos/current packets. */
@@ -130,6 +141,7 @@ struct amdtp_stream {
130 /* To wait for first packet. */ 141 /* To wait for first packet. */
131 bool callbacked; 142 bool callbacked;
132 wait_queue_head_t callback_wait; 143 wait_queue_head_t callback_wait;
144 u32 start_cycle;
133 145
134 /* For backends to process data blocks. */ 146 /* For backends to process data blocks. */
135 void *protocol; 147 void *protocol;
diff --git a/sound/firewire/bebob/bebob_command.c b/sound/firewire/bebob/bebob_command.c
index 9402cc15dbc1..f9b4225dd86f 100644
--- a/sound/firewire/bebob/bebob_command.c
+++ b/sound/firewire/bebob/bebob_command.c
@@ -31,13 +31,15 @@ int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
31 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 31 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
33 BIT(6) | BIT(7) | BIT(8)); 33 BIT(6) | BIT(7) | BIT(8));
34 if (err > 0 && err < 9) 34 if (err < 0)
35 ;
36 else if (err < 9)
35 err = -EIO; 37 err = -EIO;
36 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 38 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
37 err = -ENOSYS; 39 err = -ENOSYS;
38 else if (buf[0] == 0x0a) /* REJECTED */ 40 else if (buf[0] == 0x0a) /* REJECTED */
39 err = -EINVAL; 41 err = -EINVAL;
40 else if (err > 0) 42 else
41 err = 0; 43 err = 0;
42 44
43 kfree(buf); 45 kfree(buf);
@@ -67,7 +69,9 @@ int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
67 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 69 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
68 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 70 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
69 BIT(6) | BIT(8)); 71 BIT(6) | BIT(8));
70 if (err > 0 && err < 9) 72 if (err < 0)
73 ;
74 else if (err < 9)
71 err = -EIO; 75 err = -EIO;
72 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 76 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
73 err = -ENOSYS; 77 err = -ENOSYS;
@@ -120,7 +124,9 @@ int avc_bridgeco_get_plug_type(struct fw_unit *unit,
120 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 124 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
121 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 125 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
122 BIT(6) | BIT(7) | BIT(9)); 126 BIT(6) | BIT(7) | BIT(9));
123 if ((err >= 0) && (err < 8)) 127 if (err < 0)
128 ;
129 else if (err < 11)
124 err = -EIO; 130 err = -EIO;
125 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 131 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
126 err = -ENOSYS; 132 err = -ENOSYS;
@@ -150,7 +156,9 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
150 err = fcp_avc_transaction(unit, buf, 12, buf, 256, 156 err = fcp_avc_transaction(unit, buf, 12, buf, 256,
151 BIT(1) | BIT(2) | BIT(3) | BIT(4) | 157 BIT(1) | BIT(2) | BIT(3) | BIT(4) |
152 BIT(5) | BIT(6) | BIT(7) | BIT(9)); 158 BIT(5) | BIT(6) | BIT(7) | BIT(9));
153 if ((err >= 0) && (err < 8)) 159 if (err < 0)
160 ;
161 else if (err < 11)
154 err = -EIO; 162 err = -EIO;
155 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 163 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
156 err = -ENOSYS; 164 err = -ENOSYS;
@@ -187,7 +195,9 @@ int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
187 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 195 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
188 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 196 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
189 BIT(6) | BIT(7) | BIT(9) | BIT(10)); 197 BIT(6) | BIT(7) | BIT(9) | BIT(10));
190 if ((err >= 0) && (err < 8)) 198 if (err < 0)
199 ;
200 else if (err < 12)
191 err = -EIO; 201 err = -EIO;
192 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 202 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
193 err = -ENOSYS; 203 err = -ENOSYS;
@@ -221,7 +231,9 @@ int avc_bridgeco_get_plug_input(struct fw_unit *unit,
221 err = fcp_avc_transaction(unit, buf, 16, buf, 16, 231 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
222 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 232 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
223 BIT(6) | BIT(7)); 233 BIT(6) | BIT(7));
224 if ((err >= 0) && (err < 8)) 234 if (err < 0)
235 ;
236 else if (err < 16)
225 err = -EIO; 237 err = -EIO;
226 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 238 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
227 err = -ENOSYS; 239 err = -ENOSYS;
@@ -260,7 +272,9 @@ int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
260 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 272 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
261 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 273 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
262 BIT(6) | BIT(7) | BIT(10)); 274 BIT(6) | BIT(7) | BIT(10));
263 if ((err >= 0) && (err < 12)) 275 if (err < 0)
276 ;
277 else if (err < 12)
264 err = -EIO; 278 err = -EIO;
265 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 279 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
266 err = -ENOSYS; 280 err = -ENOSYS;
diff --git a/sound/firewire/digi00x/amdtp-dot.c b/sound/firewire/digi00x/amdtp-dot.c
index b3cffd01a19f..a4688545339c 100644
--- a/sound/firewire/digi00x/amdtp-dot.c
+++ b/sound/firewire/digi00x/amdtp-dot.c
@@ -28,6 +28,9 @@
28 */ 28 */
29#define MAX_MIDI_RX_BLOCKS 8 29#define MAX_MIDI_RX_BLOCKS 8
30 30
31/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */
32#define MAX_MIDI_PORTS 3
33
31/* 34/*
32 * The double-oh-three algorithm was discovered by Robin Gareus and Damien 35 * The double-oh-three algorithm was discovered by Robin Gareus and Damien
33 * Zammit in 2012, with reverse-engineering for Digi 003 Rack. 36 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.
@@ -42,10 +45,8 @@ struct amdtp_dot {
42 unsigned int pcm_channels; 45 unsigned int pcm_channels;
43 struct dot_state state; 46 struct dot_state state;
44 47
45 unsigned int midi_ports; 48 struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];
46 /* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */ 49 int midi_fifo_used[MAX_MIDI_PORTS];
47 struct snd_rawmidi_substream *midi[2];
48 int midi_fifo_used[2];
49 int midi_fifo_limit; 50 int midi_fifo_limit;
50 51
51 void (*transfer_samples)(struct amdtp_stream *s, 52 void (*transfer_samples)(struct amdtp_stream *s,
@@ -124,8 +125,8 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
124 return -EBUSY; 125 return -EBUSY;
125 126
126 /* 127 /*
127 * A first data channel is for MIDI conformant data channel, the rest is 128 * A first data channel is for MIDI messages, the rest is Multi Bit
128 * Multi Bit Linear Audio data channel. 129 * Linear Audio data channel.
129 */ 130 */
130 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1); 131 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);
131 if (err < 0) 132 if (err < 0)
@@ -135,11 +136,6 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
135 136
136 p->pcm_channels = pcm_channels; 137 p->pcm_channels = pcm_channels;
137 138
138 if (s->direction == AMDTP_IN_STREAM)
139 p->midi_ports = DOT_MIDI_IN_PORTS;
140 else
141 p->midi_ports = DOT_MIDI_OUT_PORTS;
142
143 /* 139 /*
144 * We do not know the actual MIDI FIFO size of most devices. Just 140 * We do not know the actual MIDI FIFO size of most devices. Just
145 * assume two bytes, i.e., one byte can be received over the bus while 141 * assume two bytes, i.e., one byte can be received over the bus while
@@ -281,13 +277,25 @@ static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer,
281 b = (u8 *)&buffer[0]; 277 b = (u8 *)&buffer[0];
282 278
283 len = 0; 279 len = 0;
284 if (port < p->midi_ports && 280 if (port < MAX_MIDI_PORTS &&
285 midi_ratelimit_per_packet(s, port) && 281 midi_ratelimit_per_packet(s, port) &&
286 p->midi[port] != NULL) 282 p->midi[port] != NULL)
287 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2); 283 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);
288 284
289 if (len > 0) { 285 if (len > 0) {
290 b[3] = (0x10 << port) | len; 286 /*
287 * Upper 4 bits of LSB represent port number.
288 * - 0000b: physical MIDI port 1.
289 * - 0010b: physical MIDI port 2.
290 * - 1110b: console MIDI port.
291 */
292 if (port == 2)
293 b[3] = 0xe0;
294 else if (port == 1)
295 b[3] = 0x20;
296 else
297 b[3] = 0x00;
298 b[3] |= len;
291 midi_use_bytes(s, port, len); 299 midi_use_bytes(s, port, len);
292 } else { 300 } else {
293 b[1] = 0; 301 b[1] = 0;
@@ -309,11 +317,22 @@ static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer,
309 317
310 for (f = 0; f < data_blocks; f++) { 318 for (f = 0; f < data_blocks; f++) {
311 b = (u8 *)&buffer[0]; 319 b = (u8 *)&buffer[0];
312 port = b[3] >> 4;
313 len = b[3] & 0x0f;
314 320
315 if (port < p->midi_ports && p->midi[port] && len > 0) 321 len = b[3] & 0x0f;
316 snd_rawmidi_receive(p->midi[port], b + 1, len); 322 if (len > 0) {
323 /*
324 * Upper 4 bits of LSB represent port number.
325 * - 0000b: physical MIDI port 1. Use port 0.
326 * - 1110b: console MIDI port. Use port 2.
327 */
328 if (b[3] >> 4 > 0)
329 port = 2;
330 else
331 port = 0;
332
333 if (port < MAX_MIDI_PORTS && p->midi[port])
334 snd_rawmidi_receive(p->midi[port], b + 1, len);
335 }
317 336
318 buffer += s->data_block_quadlets; 337 buffer += s->data_block_quadlets;
319 } 338 }
@@ -364,7 +383,7 @@ void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port,
364{ 383{
365 struct amdtp_dot *p = s->protocol; 384 struct amdtp_dot *p = s->protocol;
366 385
367 if (port < p->midi_ports) 386 if (port < MAX_MIDI_PORTS)
368 ACCESS_ONCE(p->midi[port]) = midi; 387 ACCESS_ONCE(p->midi[port]) = midi;
369} 388}
370 389
diff --git a/sound/firewire/digi00x/digi00x-midi.c b/sound/firewire/digi00x/digi00x-midi.c
index 915d2a21223e..7ab3d0810f6b 100644
--- a/sound/firewire/digi00x/digi00x-midi.c
+++ b/sound/firewire/digi00x/digi00x-midi.c
@@ -8,7 +8,7 @@
8 8
9#include "digi00x.h" 9#include "digi00x.h"
10 10
11static int midi_phys_open(struct snd_rawmidi_substream *substream) 11static int midi_open(struct snd_rawmidi_substream *substream)
12{ 12{
13 struct snd_dg00x *dg00x = substream->rmidi->private_data; 13 struct snd_dg00x *dg00x = substream->rmidi->private_data;
14 int err; 14 int err;
@@ -27,7 +27,7 @@ static int midi_phys_open(struct snd_rawmidi_substream *substream)
27 return err; 27 return err;
28} 28}
29 29
30static int midi_phys_close(struct snd_rawmidi_substream *substream) 30static int midi_close(struct snd_rawmidi_substream *substream)
31{ 31{
32 struct snd_dg00x *dg00x = substream->rmidi->private_data; 32 struct snd_dg00x *dg00x = substream->rmidi->private_data;
33 33
@@ -40,180 +40,130 @@ static int midi_phys_close(struct snd_rawmidi_substream *substream)
40 return 0; 40 return 0;
41} 41}
42 42
43static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, 43static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
44 int up) 44 int up)
45{ 45{
46 struct snd_dg00x *dg00x = substream->rmidi->private_data; 46 struct snd_dg00x *dg00x = substream->rmidi->private_data;
47 unsigned int port;
47 unsigned long flags; 48 unsigned long flags;
48 49
49 spin_lock_irqsave(&dg00x->lock, flags); 50 if (substream->rmidi->device == 0)
50 51 port = substream->number;
51 if (up)
52 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number,
53 substream);
54 else 52 else
55 amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, 53 port = 2;
56 NULL);
57
58 spin_unlock_irqrestore(&dg00x->lock, flags);
59}
60
61static 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 54
67 spin_lock_irqsave(&dg00x->lock, flags); 55 spin_lock_irqsave(&dg00x->lock, flags);
68 56
69 if (up) 57 if (up)
70 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 58 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
71 substream);
72 else 59 else
73 amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 60 amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
74 NULL);
75 61
76 spin_unlock_irqrestore(&dg00x->lock, flags); 62 spin_unlock_irqrestore(&dg00x->lock, flags);
77} 63}
78 64
79static int midi_ctl_open(struct snd_rawmidi_substream *substream) 65static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
80{ 66 int up)
81 /* Do nothing. */
82 return 0;
83}
84
85static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream)
86{
87 /* Do nothing. */
88 return 0;
89}
90
91static 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
100static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream,
101 int up)
102{ 67{
103 struct snd_dg00x *dg00x = substream->rmidi->private_data; 68 struct snd_dg00x *dg00x = substream->rmidi->private_data;
69 unsigned int port;
104 unsigned long flags; 70 unsigned long flags;
105 71
106 spin_lock_irqsave(&dg00x->lock, flags); 72 if (substream->rmidi->device == 0)
107 73 port = substream->number;
108 if (up)
109 dg00x->in_control = substream;
110 else 74 else
111 dg00x->in_control = NULL; 75 port = 2;
112
113 spin_unlock_irqrestore(&dg00x->lock, flags);
114}
115
116static 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 76
122 spin_lock_irqsave(&dg00x->lock, flags); 77 spin_lock_irqsave(&dg00x->lock, flags);
123 78
124 if (up) 79 if (up)
125 snd_fw_async_midi_port_run(&dg00x->out_control, substream); 80 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
81 else
82 amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
126 83
127 spin_unlock_irqrestore(&dg00x->lock, flags); 84 spin_unlock_irqrestore(&dg00x->lock, flags);
128} 85}
129 86
130static void set_midi_substream_names(struct snd_dg00x *dg00x, 87static void set_substream_names(struct snd_dg00x *dg00x,
131 struct snd_rawmidi_str *str, 88 struct snd_rawmidi *rmidi, bool is_console)
132 bool is_ctl)
133{ 89{
134 struct snd_rawmidi_substream *subs; 90 struct snd_rawmidi_substream *subs;
135 91 struct snd_rawmidi_str *str;
136 list_for_each_entry(subs, &str->substreams, list) { 92 int i;
137 if (!is_ctl) 93
138 snprintf(subs->name, sizeof(subs->name), 94 for (i = 0; i < 2; ++i) {
139 "%s MIDI %d", 95 str = &rmidi->streams[i];
140 dg00x->card->shortname, subs->number + 1); 96
141 else 97 list_for_each_entry(subs, &str->substreams, list) {
142 /* This port is for asynchronous transaction. */ 98 if (!is_console) {
143 snprintf(subs->name, sizeof(subs->name), 99 snprintf(subs->name, sizeof(subs->name),
144 "%s control", 100 "%s MIDI %d",
145 dg00x->card->shortname); 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 }
146 } 109 }
147} 110}
148 111
149int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) 112static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,
113 unsigned int in_ports, bool is_console)
150{ 114{
151 static const struct snd_rawmidi_ops phys_capture_ops = { 115 static const struct snd_rawmidi_ops capture_ops = {
152 .open = midi_phys_open, 116 .open = midi_open,
153 .close = midi_phys_close, 117 .close = midi_close,
154 .trigger = midi_phys_capture_trigger, 118 .trigger = midi_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 }; 119 };
161 static const struct snd_rawmidi_ops ctl_capture_ops = { 120 static const struct snd_rawmidi_ops playback_ops = {
162 .open = midi_ctl_open, 121 .open = midi_open,
163 .close = midi_ctl_capture_close, 122 .close = midi_close,
164 .trigger = midi_ctl_capture_trigger, 123 .trigger = midi_playback_trigger,
165 }; 124 };
166 static const struct snd_rawmidi_ops ctl_playback_ops = { 125 const char *label;
167 .open = midi_ctl_open, 126 struct snd_rawmidi *rmidi;
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; 127 int err;
175 128
176 /* Add physical midi ports. */ 129 /* Add physical midi ports. */
177 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, 130 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console,
178 DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]); 131 out_ports, in_ports, &rmidi);
179 if (err < 0) 132 if (err < 0)
180 return err; 133 return err;
134 rmidi->private_data = dg00x;
181 135
182 snprintf(rmidi[0]->name, sizeof(rmidi[0]->name), 136 if (!is_console)
183 "%s MIDI", dg00x->card->shortname); 137 label = "%s control";
184 138 else
185 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT, 139 label = "%s MIDI";
186 &phys_capture_ops); 140 snprintf(rmidi->name, sizeof(rmidi->name), label,
187 snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT, 141 dg00x->card->shortname);
188 &phys_playback_ops);
189 142
190 /* Add a pair of control midi ports. */ 143 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops);
191 err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1, 144 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops);
192 1, 1, &rmidi[1]);
193 if (err < 0)
194 return err;
195 145
196 snprintf(rmidi[1]->name, sizeof(rmidi[1]->name), 146 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT |
197 "%s control", dg00x->card->shortname); 147 SNDRV_RAWMIDI_INFO_OUTPUT |
148 SNDRV_RAWMIDI_INFO_DUPLEX;
198 149
199 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT, 150 set_substream_names(dg00x, rmidi, is_console);
200 &ctl_capture_ops);
201 snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT,
202 &ctl_playback_ops);
203 151
204 for (i = 0; i < ARRAY_SIZE(rmidi); i++) { 152 return 0;
205 rmidi[i]->private_data = dg00x; 153}
206 154
207 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 155int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x)
208 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT]; 156{
209 set_midi_substream_names(dg00x, str, i); 157 int err;
210 158
211 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 159 /* Add physical midi ports. */
212 str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; 160 err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS,
213 set_midi_substream_names(dg00x, str, i); 161 false);
162 if (err < 0)
163 return err;
214 164
215 rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 165 if (dg00x->is_console)
216 } 166 err = add_substream_pair(dg00x, 1, 1, true);
217 167
218 return 0; 168 return err;
219} 169}
diff --git a/sound/firewire/digi00x/digi00x-transaction.c b/sound/firewire/digi00x/digi00x-transaction.c
index 735d35640807..af9bc8504781 100644
--- a/sound/firewire/digi00x/digi00x-transaction.c
+++ b/sound/firewire/digi00x/digi00x-transaction.c
@@ -9,40 +9,6 @@
9#include <sound/asound.h> 9#include <sound/asound.h>
10#include "digi00x.h" 10#include "digi00x.h"
11 11
12static 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
24static 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
46static void handle_unknown_message(struct snd_dg00x *dg00x, 12static void handle_unknown_message(struct snd_dg00x *dg00x,
47 unsigned long long offset, __be32 *buf) 13 unsigned long long offset, __be32 *buf)
48{ 14{
@@ -63,39 +29,36 @@ static void handle_message(struct fw_card *card, struct fw_request *request,
63 struct snd_dg00x *dg00x = callback_data; 29 struct snd_dg00x *dg00x = callback_data;
64 __be32 *buf = (__be32 *)data; 30 __be32 *buf = (__be32 *)data;
65 31
32 fw_send_response(card, request, RCODE_COMPLETE);
33
66 if (offset == dg00x->async_handler.offset) 34 if (offset == dg00x->async_handler.offset)
67 handle_unknown_message(dg00x, offset, buf); 35 handle_unknown_message(dg00x, offset, buf);
68 else if (offset == dg00x->async_handler.offset + 4)
69 handle_midi_control(dg00x, buf, length);
70
71 fw_send_response(card, request, RCODE_COMPLETE);
72} 36}
73 37
74int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x) 38int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x)
75{ 39{
76 struct fw_device *device = fw_parent_device(dg00x->unit); 40 struct fw_device *device = fw_parent_device(dg00x->unit);
77 __be32 data[2]; 41 __be32 data[2];
78 int err;
79 42
80 /* Unknown. 4bytes. */ 43 /* Unknown. 4bytes. */
81 data[0] = cpu_to_be32((device->card->node_id << 16) | 44 data[0] = cpu_to_be32((device->card->node_id << 16) |
82 (dg00x->async_handler.offset >> 32)); 45 (dg00x->async_handler.offset >> 32));
83 data[1] = cpu_to_be32(dg00x->async_handler.offset); 46 data[1] = cpu_to_be32(dg00x->async_handler.offset);
84 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
85 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
86 &data, sizeof(data), 0);
87 if (err < 0)
88 return err;
89
90 /* Asynchronous transactions for MIDI control message. */
91 data[0] = cpu_to_be32((device->card->node_id << 16) |
92 (dg00x->async_handler.offset >> 32));
93 data[1] = cpu_to_be32(dg00x->async_handler.offset + 4);
94 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST, 47 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST,
95 DG00X_ADDR_BASE + DG00X_OFFSET_MIDI_CTL_ADDR, 48 DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR,
96 &data, sizeof(data), 0); 49 &data, sizeof(data), 0);
97} 50}
98 51
52void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
53{
54 if (dg00x->async_handler.callback_data == NULL)
55 return;
56
57 fw_core_remove_address_handler(&dg00x->async_handler);
58
59 dg00x->async_handler.callback_data = NULL;
60}
61
99int snd_dg00x_transaction_register(struct snd_dg00x *dg00x) 62int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
100{ 63{
101 static const struct fw_address_region resp_register_region = { 64 static const struct fw_address_region resp_register_region = {
@@ -104,7 +67,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
104 }; 67 };
105 int err; 68 int err;
106 69
107 dg00x->async_handler.length = 12; 70 dg00x->async_handler.length = 4;
108 dg00x->async_handler.address_callback = handle_message; 71 dg00x->async_handler.address_callback = handle_message;
109 dg00x->async_handler.callback_data = dg00x; 72 dg00x->async_handler.callback_data = dg00x;
110 73
@@ -115,28 +78,7 @@ int snd_dg00x_transaction_register(struct snd_dg00x *dg00x)
115 78
116 err = snd_dg00x_transaction_reregister(dg00x); 79 err = snd_dg00x_transaction_reregister(dg00x);
117 if (err < 0) 80 if (err < 0)
118 goto error; 81 snd_dg00x_transaction_unregister(dg00x);
119
120 err = snd_fw_async_midi_port_init(&dg00x->out_control, dg00x->unit,
121 DG00X_ADDR_BASE + DG00X_OFFSET_MMC,
122 4, fill_midi_message);
123 if (err < 0)
124 goto error;
125 82
126 return err; 83 return err;
127error:
128 fw_core_remove_address_handler(&dg00x->async_handler);
129 dg00x->async_handler.callback_data = NULL;
130 return err;
131}
132
133void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x)
134{
135 if (dg00x->async_handler.callback_data == NULL)
136 return;
137
138 snd_fw_async_midi_port_destroy(&dg00x->out_control);
139 fw_core_remove_address_handler(&dg00x->async_handler);
140
141 dg00x->async_handler.callback_data = NULL;
142} 84}
diff --git a/sound/firewire/digi00x/digi00x.c b/sound/firewire/digi00x/digi00x.c
index cc4776c6ded3..1f5e1d23f31a 100644
--- a/sound/firewire/digi00x/digi00x.c
+++ b/sound/firewire/digi00x/digi00x.c
@@ -13,7 +13,8 @@ MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
13MODULE_LICENSE("GPL v2"); 13MODULE_LICENSE("GPL v2");
14 14
15#define VENDOR_DIGIDESIGN 0x00a07e 15#define VENDOR_DIGIDESIGN 0x00a07e
16#define MODEL_DIGI00X 0x000002 16#define MODEL_CONSOLE 0x000001
17#define MODEL_RACK 0x000002
17 18
18static int name_card(struct snd_dg00x *dg00x) 19static int name_card(struct snd_dg00x *dg00x)
19{ 20{
@@ -129,6 +130,8 @@ static int snd_dg00x_probe(struct fw_unit *unit,
129 spin_lock_init(&dg00x->lock); 130 spin_lock_init(&dg00x->lock);
130 init_waitqueue_head(&dg00x->hwdep_wait); 131 init_waitqueue_head(&dg00x->hwdep_wait);
131 132
133 dg00x->is_console = entry->model_id == MODEL_CONSOLE;
134
132 /* Allocate and register this sound card later. */ 135 /* Allocate and register this sound card later. */
133 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); 136 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration);
134 snd_fw_schedule_registration(unit, &dg00x->dwork); 137 snd_fw_schedule_registration(unit, &dg00x->dwork);
@@ -183,7 +186,13 @@ static const struct ieee1394_device_id snd_dg00x_id_table[] = {
183 .match_flags = IEEE1394_MATCH_VENDOR_ID | 186 .match_flags = IEEE1394_MATCH_VENDOR_ID |
184 IEEE1394_MATCH_MODEL_ID, 187 IEEE1394_MATCH_MODEL_ID,
185 .vendor_id = VENDOR_DIGIDESIGN, 188 .vendor_id = VENDOR_DIGIDESIGN,
186 .model_id = MODEL_DIGI00X, 189 .model_id = MODEL_CONSOLE,
190 },
191 {
192 .match_flags = IEEE1394_MATCH_VENDOR_ID |
193 IEEE1394_MATCH_MODEL_ID,
194 .vendor_id = VENDOR_DIGIDESIGN,
195 .model_id = MODEL_RACK,
187 }, 196 },
188 {} 197 {}
189}; 198};
diff --git a/sound/firewire/digi00x/digi00x.h b/sound/firewire/digi00x/digi00x.h
index 9dc761bdacca..1275a50956c0 100644
--- a/sound/firewire/digi00x/digi00x.h
+++ b/sound/firewire/digi00x/digi00x.h
@@ -58,16 +58,15 @@ struct snd_dg00x {
58 struct fw_address_handler async_handler; 58 struct fw_address_handler async_handler;
59 u32 msg; 59 u32 msg;
60 60
61 /* For asynchronous MIDI controls. */ 61 /* Console models have additional MIDI ports for control surface. */
62 struct snd_rawmidi_substream *in_control; 62 bool is_console;
63 struct snd_fw_async_midi_port out_control;
64}; 63};
65 64
66#define DG00X_ADDR_BASE 0xffffe0000000ull 65#define DG00X_ADDR_BASE 0xffffe0000000ull
67 66
68#define DG00X_OFFSET_STREAMING_STATE 0x0000 67#define DG00X_OFFSET_STREAMING_STATE 0x0000
69#define DG00X_OFFSET_STREAMING_SET 0x0004 68#define DG00X_OFFSET_STREAMING_SET 0x0004
70#define DG00X_OFFSET_MIDI_CTL_ADDR 0x0008 69/* unknown but address in host space 0x0008 */
71/* For LSB of the address 0x000c */ 70/* For LSB of the address 0x000c */
72/* unknown 0x0010 */ 71/* unknown 0x0010 */
73#define DG00X_OFFSET_MESSAGE_ADDR 0x0014 72#define DG00X_OFFSET_MESSAGE_ADDR 0x0014
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
index cce19768f43d..61dda828f767 100644
--- a/sound/firewire/fcp.c
+++ b/sound/firewire/fcp.c
@@ -63,7 +63,9 @@ int avc_general_set_sig_fmt(struct fw_unit *unit, unsigned int rate,
63 /* do transaction and check buf[1-5] are the same against command */ 63 /* do transaction and check buf[1-5] are the same against command */
64 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 64 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
66 if (err >= 0 && err < 8) 66 if (err < 0)
67 ;
68 else if (err < 8)
67 err = -EIO; 69 err = -EIO;
68 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 70 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
69 err = -ENOSYS; 71 err = -ENOSYS;
@@ -106,7 +108,9 @@ int avc_general_get_sig_fmt(struct fw_unit *unit, unsigned int *rate,
106 /* do transaction and check buf[1-4] are the same against command */ 108 /* do transaction and check buf[1-4] are the same against command */
107 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 109 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
108 BIT(1) | BIT(2) | BIT(3) | BIT(4)); 110 BIT(1) | BIT(2) | BIT(3) | BIT(4));
109 if (err >= 0 && err < 8) 111 if (err < 0)
112 ;
113 else if (err < 8)
110 err = -EIO; 114 err = -EIO;
111 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 115 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
112 err = -ENOSYS; 116 err = -ENOSYS;
@@ -154,7 +158,9 @@ int avc_general_get_plug_info(struct fw_unit *unit, unsigned int subunit_type,
154 buf[3] = 0xff & subfunction; 158 buf[3] = 0xff & subfunction;
155 159
156 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); 160 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));
157 if (err >= 0 && err < 8) 161 if (err < 0)
162 ;
163 else if (err < 8)
158 err = -EIO; 164 err = -EIO;
159 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 165 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
160 err = -ENOSYS; 166 err = -ENOSYS;
diff --git a/sound/firewire/fireface/Makefile b/sound/firewire/fireface/Makefile
new file mode 100644
index 000000000000..8f807284ba54
--- /dev/null
+++ b/sound/firewire/fireface/Makefile
@@ -0,0 +1,3 @@
1snd-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
3obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o
diff --git a/sound/firewire/fireface/amdtp-ff.c b/sound/firewire/fireface/amdtp-ff.c
new file mode 100644
index 000000000000..780da9deb2f0
--- /dev/null
+++ b/sound/firewire/fireface/amdtp-ff.c
@@ -0,0 +1,155 @@
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
12struct amdtp_ff {
13 unsigned int pcm_channels;
14};
15
16int 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
31static 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
56static 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
81static 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
94int 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
106static 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
125static 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
143int 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}
diff --git a/sound/firewire/fireface/ff-hwdep.c b/sound/firewire/fireface/ff-hwdep.c
new file mode 100644
index 000000000000..3ee04b054585
--- /dev/null
+++ b/sound/firewire/fireface/ff-hwdep.c
@@ -0,0 +1,191 @@
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
19static 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
55static 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
73static 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
92static 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
110static 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
128static 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
140static 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
158static 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
168int 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}
diff --git a/sound/firewire/fireface/ff-midi.c b/sound/firewire/fireface/ff-midi.c
new file mode 100644
index 000000000000..29ee0a7365c3
--- /dev/null
+++ b/sound/firewire/fireface/ff-midi.c
@@ -0,0 +1,131 @@
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
11static int midi_capture_open(struct snd_rawmidi_substream *substream)
12{
13 /* Do nothing. */
14 return 0;
15}
16
17static 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
30static int midi_capture_close(struct snd_rawmidi_substream *substream)
31{
32 /* Do nothing. */
33 return 0;
34}
35
36static 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
46static 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
63static 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
77static struct snd_rawmidi_ops midi_capture_ops = {
78 .open = midi_capture_open,
79 .close = midi_capture_close,
80 .trigger = midi_capture_trigger,
81};
82
83static struct snd_rawmidi_ops midi_playback_ops = {
84 .open = midi_playback_open,
85 .close = midi_playback_close,
86 .trigger = midi_playback_trigger,
87};
88
89static 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
100int 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}
diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c
new file mode 100644
index 000000000000..93cee1978e8e
--- /dev/null
+++ b/sound/firewire/fireface/ff-pcm.c
@@ -0,0 +1,409 @@
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
11static inline unsigned int get_multiplier_mode_with_index(unsigned int index)
12{
13 return ((int)index - 1) / 2;
14}
15
16static 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
41static 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
66static 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
94static 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
106static 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
150static 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
203static 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
212static 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
232static 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
252static 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
268static 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
284static 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
301static 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
318static 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
336static 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
354static 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
361static 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
368static 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
380static 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
393int 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}
diff --git a/sound/firewire/fireface/ff-proc.c b/sound/firewire/fireface/ff-proc.c
new file mode 100644
index 000000000000..69441d121f71
--- /dev/null
+++ b/sound/firewire/fireface/ff-proc.c
@@ -0,0 +1,63 @@
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
11static 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
19static 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
27static 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
43void 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}
diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c
new file mode 100644
index 000000000000..fcec6de80eeb
--- /dev/null
+++ b/sound/firewire/fireface/ff-protocol-ff400.c
@@ -0,0 +1,371 @@
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
25static 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
84static 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
136static 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
145static 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
171static 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
284static 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
359struct 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};
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
new file mode 100644
index 000000000000..78880922120e
--- /dev/null
+++ b/sound/firewire/fireface/ff-stream.c
@@ -0,0 +1,282 @@
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
13static 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 */
34static 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
70static 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
76static 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
82static 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
107static 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
118int 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);
129end:
130 return err;
131}
132
133/*
134 * This function should be called before starting streams or after stopping
135 * streams.
136 */
137void 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
143int 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;
211error:
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
221void 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
232void 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
245void snd_ff_stream_lock_changed(struct snd_ff *ff)
246{
247 ff->dev_lock_changed = true;
248 wake_up(&ff->hwdep_wait);
249}
250
251int 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;
267end:
268 spin_unlock_irq(&ff->lock);
269 return err;
270}
271
272void 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);
280end:
281 spin_unlock_irq(&ff->lock);
282}
diff --git a/sound/firewire/fireface/ff-transaction.c b/sound/firewire/fireface/ff-transaction.c
new file mode 100644
index 000000000000..dd6c8e839647
--- /dev/null
+++ b/sound/firewire/fireface/ff-transaction.c
@@ -0,0 +1,295 @@
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
11static 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
36static 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
45static 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
54static 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
60static 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
122static 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
129static 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
136static 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
181static 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 */
237int 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
254int 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
280void 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}
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
new file mode 100644
index 000000000000..eee7c8eac7a6
--- /dev/null
+++ b/sound/firewire/fireface/ff.c
@@ -0,0 +1,209 @@
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
13MODULE_DESCRIPTION("RME Fireface series Driver");
14MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
15MODULE_LICENSE("GPL v2");
16
17static 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
30static 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
41static void ff_card_free(struct snd_card *card)
42{
43 ff_free(card->private_data);
44}
45
46static 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;
92error:
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
100static 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
126static 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
140static 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
160static 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
169static 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};
184MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
185
186static 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
198static int __init snd_ff_init(void)
199{
200 return driver_register(&ff_driver.driver);
201}
202
203static void __exit snd_ff_exit(void)
204{
205 driver_unregister(&ff_driver.driver);
206}
207
208module_init(snd_ff_init);
209module_exit(snd_ff_exit);
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
new file mode 100644
index 000000000000..3cb812a50030
--- /dev/null
+++ b/sound/firewire/fireface/ff.h
@@ -0,0 +1,146 @@
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
40struct snd_ff_protocol;
41struct 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
53struct 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
89enum 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
98struct 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
115extern struct snd_ff_protocol snd_ff_protocol_ff400;
116
117int snd_ff_transaction_register(struct snd_ff *ff);
118int snd_ff_transaction_reregister(struct snd_ff *ff);
119void snd_ff_transaction_unregister(struct snd_ff *ff);
120
121int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,
122 unsigned int pcm_channels);
123int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,
124 struct snd_pcm_runtime *runtime);
125int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
126 enum amdtp_stream_direction dir);
127
128int snd_ff_stream_init_duplex(struct snd_ff *ff);
129void snd_ff_stream_destroy_duplex(struct snd_ff *ff);
130int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate);
131void snd_ff_stream_stop_duplex(struct snd_ff *ff);
132void snd_ff_stream_update_duplex(struct snd_ff *ff);
133
134void snd_ff_stream_lock_changed(struct snd_ff *ff);
135int snd_ff_stream_lock_try(struct snd_ff *ff);
136void snd_ff_stream_lock_release(struct snd_ff *ff);
137
138void snd_ff_proc_init(struct snd_ff *ff);
139
140int snd_ff_create_midi_devices(struct snd_ff *ff);
141
142int snd_ff_create_pcm_devices(struct snd_ff *ff);
143
144int snd_ff_create_hwdep_devices(struct snd_ff *ff);
145
146#endif
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index 7683238283b6..39dfa74906ef 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -99,147 +99,6 @@ void snd_fw_schedule_registration(struct fw_unit *unit,
99} 99}
100EXPORT_SYMBOL(snd_fw_schedule_registration); 100EXPORT_SYMBOL(snd_fw_schedule_registration);
101 101
102static 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
128static 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 */
209int 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}
229EXPORT_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 */
235void 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}
241EXPORT_SYMBOL(snd_fw_async_midi_port_destroy);
242
243MODULE_DESCRIPTION("FireWire audio helper functions"); 102MODULE_DESCRIPTION("FireWire audio helper functions");
244MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 103MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
245MODULE_LICENSE("GPL v2"); 104MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index c3768cd494a5..eef70922ed89 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -25,58 +25,4 @@ static inline bool rcode_is_permanent_error(int rcode)
25void snd_fw_schedule_registration(struct fw_unit *unit, 25void snd_fw_schedule_registration(struct fw_unit *unit,
26 struct delayed_work *dwork); 26 struct delayed_work *dwork);
27 27
28struct snd_fw_async_midi_port;
29typedef int (*snd_fw_async_midi_port_fill)(
30 struct snd_rawmidi_substream *substream,
31 u8 *buf);
32
33struct 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
51int 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);
54void 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 */
61static inline void
62snd_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 */
75static inline void
76snd_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 28#endif
diff --git a/sound/firewire/motu/Makefile b/sound/firewire/motu/Makefile
new file mode 100644
index 000000000000..728f586e754b
--- /dev/null
+++ b/sound/firewire/motu/Makefile
@@ -0,0 +1,6 @@
1CFLAGS_amdtp-motu.o := -I$(src)
2
3snd-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
6obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
diff --git a/sound/firewire/motu/amdtp-motu-trace.h b/sound/firewire/motu/amdtp-motu-trace.h
new file mode 100644
index 000000000000..cd0cbfa9f96f
--- /dev/null
+++ b/sound/firewire/motu/amdtp-motu-trace.h
@@ -0,0 +1,123 @@
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
16static void copy_sph(u32 *frame, __be32 *buffer, unsigned int data_blocks,
17 unsigned int data_block_quadlets);
18static void copy_message(u64 *frames, __be32 *buffer, unsigned int data_blocks,
19 unsigned int data_block_quadlets);
20
21TRACE_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
45TRACE_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
69TRACE_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
93TRACE_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>
diff --git a/sound/firewire/motu/amdtp-motu.c b/sound/firewire/motu/amdtp-motu.c
new file mode 100644
index 000000000000..96f0091144bb
--- /dev/null
+++ b/sound/firewire/motu/amdtp-motu.c
@@ -0,0 +1,427 @@
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
26struct 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
47int 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
121static 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
149static 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
180static 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
203int 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
216void 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
225static 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
251static 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. */
271static 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. */
285static 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
300static 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
320static 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
343static 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
362static 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
391int 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}
diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c
new file mode 100644
index 000000000000..b87ccb69d597
--- /dev/null
+++ b/sound/firewire/motu/motu-hwdep.c
@@ -0,0 +1,198 @@
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
20static 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
62static 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
80static 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
99static 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
117static 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
135static 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
147static 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
165static 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
175int 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}
diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c
new file mode 100644
index 000000000000..e3acfcc53f4e
--- /dev/null
+++ b/sound/firewire/motu/motu-midi.c
@@ -0,0 +1,169 @@
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
10static 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
32static 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
54static 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
69static 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
84static 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
101static 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
118static 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
129int 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}
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c
new file mode 100644
index 000000000000..94558f3d218b
--- /dev/null
+++ b/sound/firewire/motu/motu-pcm.c
@@ -0,0 +1,398 @@
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
12static 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
42static 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
72static 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
99static 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
111static 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
154static 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;
198err_locked:
199 mutex_unlock(&motu->mutex);
200 snd_motu_stream_lock_release(motu);
201 return err;
202}
203
204static 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
213static 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}
232static 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
252static 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
268static 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
284static 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}
297static 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
311static 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}
328static 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
346static 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}
352static 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
359int 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}
diff --git a/sound/firewire/motu/motu-proc.c b/sound/firewire/motu/motu-proc.c
new file mode 100644
index 000000000000..4edc064999ed
--- /dev/null
+++ b/sound/firewire/motu/motu-proc.c
@@ -0,0 +1,118 @@
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
11static 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
25static 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
43static 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
82static 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
98void 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}
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c
new file mode 100644
index 000000000000..05b5d287c2f3
--- /dev/null
+++ b/sound/firewire/motu/motu-protocol-v2.c
@@ -0,0 +1,237 @@
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
26static 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
46static 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
74static 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
122static 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
128static 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
175static 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
198static 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
231const 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};
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c
new file mode 100644
index 000000000000..ddb647254ed2
--- /dev/null
+++ b/sound/firewire/motu/motu-protocol-v3.c
@@ -0,0 +1,311 @@
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
28static 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
49static 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
89static 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
135static 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
157static 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
216static 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
268static 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
305const 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};
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
new file mode 100644
index 000000000000..bd458029099e
--- /dev/null
+++ b/sound/firewire/motu/motu-stream.c
@@ -0,0 +1,381 @@
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
29static 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
80static 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
107static 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
131static 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
144static 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
170int 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
258void 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
272static 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
299static 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
317int 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 */
336void 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
345static void motu_lock_changed(struct snd_motu *motu)
346{
347 motu->dev_lock_changed = true;
348 wake_up(&motu->hwdep_wait);
349}
350
351int 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;
365out:
366 spin_unlock_irq(&motu->lock);
367 return err;
368}
369
370void 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);
379out:
380 spin_unlock_irq(&motu->lock);
381}
diff --git a/sound/firewire/motu/motu-transaction.c b/sound/firewire/motu/motu-transaction.c
new file mode 100644
index 000000000000..7fc30091e0de
--- /dev/null
+++ b/sound/firewire/motu/motu-transaction.c
@@ -0,0 +1,137 @@
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
16int 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
32int 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
48static 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
76int 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
98int 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
125void 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}
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c
new file mode 100644
index 000000000000..bf779cfeef0d
--- /dev/null
+++ b/sound/firewire/motu/motu.c
@@ -0,0 +1,264 @@
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
13MODULE_DESCRIPTION("MOTU FireWire driver");
14MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
15MODULE_LICENSE("GPL v2");
16
17const 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
29static 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
55static 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 */
72static void motu_card_free(struct snd_card *card)
73{
74 motu_free(card->private_data);
75}
76
77static 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;
129error:
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
136static 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
161static 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
181static 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
193static 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
206static 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
233static 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};
239MODULE_DEVICE_TABLE(ieee1394, motu_id_table);
240
241static 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
253static int __init alsa_motu_init(void)
254{
255 return driver_register(&motu_driver.driver);
256}
257
258static void __exit alsa_motu_exit(void)
259{
260 driver_unregister(&motu_driver.driver);
261}
262
263module_init(alsa_motu_init);
264module_exit(alsa_motu_exit);
diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h
new file mode 100644
index 000000000000..8d6a4a3af9cc
--- /dev/null
+++ b/sound/firewire/motu/motu.h
@@ -0,0 +1,161 @@
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
34struct 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
44struct 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
76enum 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
89extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT];
90
91enum 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
106struct 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
115struct 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
125extern const struct snd_motu_protocol snd_motu_protocol_v2;
126extern const struct snd_motu_protocol snd_motu_protocol_v3;
127
128int 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);
131int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
132 unsigned int midi_ports,
133 struct snd_motu_packet_format *formats);
134int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
135 struct snd_pcm_runtime *runtime);
136void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
137 struct snd_rawmidi_substream *midi);
138
139int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
140 size_t size);
141int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
142 size_t size);
143int snd_motu_transaction_register(struct snd_motu *motu);
144int snd_motu_transaction_reregister(struct snd_motu *motu);
145void snd_motu_transaction_unregister(struct snd_motu *motu);
146
147int snd_motu_stream_init_duplex(struct snd_motu *motu);
148void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
149int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate);
150void snd_motu_stream_stop_duplex(struct snd_motu *motu);
151int snd_motu_stream_lock_try(struct snd_motu *motu);
152void snd_motu_stream_lock_release(struct snd_motu *motu);
153
154void snd_motu_proc_init(struct snd_motu *motu);
155
156int snd_motu_create_pcm_devices(struct snd_motu *motu);
157
158int snd_motu_create_midi_devices(struct snd_motu *motu);
159
160int snd_motu_create_hwdep_device(struct snd_motu *motu);
161#endif
diff --git a/sound/firewire/oxfw/oxfw-command.c b/sound/firewire/oxfw/oxfw-command.c
index 12ef3253bc89..ac3e2e301666 100644
--- a/sound/firewire/oxfw/oxfw-command.c
+++ b/sound/firewire/oxfw/oxfw-command.c
@@ -34,7 +34,9 @@ int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, 34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10,
35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
36 BIT(6) | BIT(7) | BIT(8)); 36 BIT(6) | BIT(7) | BIT(8));
37 if ((err > 0) && (err < len + 10)) 37 if (err < 0)
38 ;
39 else if (err < len + 10)
38 err = -EIO; 40 err = -EIO;
39 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 41 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
40 err = -ENOSYS; 42 err = -ENOSYS;
@@ -77,7 +79,9 @@ int avc_stream_get_format(struct fw_unit *unit,
77 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 79 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
78 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 80 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
79 BIT(6) | BIT(7)); 81 BIT(6) | BIT(7));
80 if ((err > 0) && (err < 10)) 82 if (err < 0)
83 ;
84 else if (err < 12)
81 err = -EIO; 85 err = -EIO;
82 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 86 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
83 err = -ENOSYS; 87 err = -ENOSYS;
@@ -139,7 +143,9 @@ int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
139 /* do transaction and check buf[1-5] are the same against command */ 143 /* do transaction and check buf[1-5] are the same against command */
140 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 144 err = fcp_avc_transaction(unit, buf, 8, buf, 8,
141 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 145 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
142 if ((err > 0) && (err < 8)) 146 if (err < 0)
147 ;
148 else if (err < 8)
143 err = -EIO; 149 err = -EIO;
144 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 150 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
145 err = -ENOSYS; 151 err = -ENOSYS;
diff --git a/sound/firewire/tascam/tascam-midi.c b/sound/firewire/tascam/tascam-midi.c
index df4f95d65925..4a741570d536 100644
--- a/sound/firewire/tascam/tascam-midi.c
+++ b/sound/firewire/tascam/tascam-midi.c
@@ -18,9 +18,8 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream)
18{ 18{
19 struct snd_tscm *tscm = substream->rmidi->private_data; 19 struct snd_tscm *tscm = substream->rmidi->private_data;
20 20
21 /* Initialize internal status. */ 21 snd_fw_async_midi_port_init(&tscm->out_ports[substream->number]);
22 tscm->running_status[substream->number] = 0; 22
23 tscm->on_sysex[substream->number] = 0;
24 return 0; 23 return 0;
25} 24}
26 25
@@ -32,11 +31,14 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream)
32 31
33static int midi_playback_close(struct snd_rawmidi_substream *substream) 32static int midi_playback_close(struct snd_rawmidi_substream *substream)
34{ 33{
34 return 0;
35}
36
37static void midi_playback_drain(struct snd_rawmidi_substream *substream)
38{
35 struct snd_tscm *tscm = substream->rmidi->private_data; 39 struct snd_tscm *tscm = substream->rmidi->private_data;
36 40
37 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]); 41 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]);
38
39 return 0;
40} 42}
41 43
42static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) 44static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
@@ -78,6 +80,7 @@ int snd_tscm_create_midi_devices(struct snd_tscm *tscm)
78 static const struct snd_rawmidi_ops playback_ops = { 80 static const struct snd_rawmidi_ops playback_ops = {
79 .open = midi_playback_open, 81 .open = midi_playback_open,
80 .close = midi_playback_close, 82 .close = midi_playback_close,
83 .drain = midi_playback_drain,
81 .trigger = midi_playback_trigger, 84 .trigger = midi_playback_trigger,
82 }; 85 };
83 struct snd_rawmidi *rmidi; 86 struct snd_rawmidi *rmidi;
diff --git a/sound/firewire/tascam/tascam-transaction.c b/sound/firewire/tascam/tascam-transaction.c
index 040a96d1ba8e..8967c52f5032 100644
--- a/sound/firewire/tascam/tascam-transaction.c
+++ b/sound/firewire/tascam/tascam-transaction.c
@@ -58,39 +58,38 @@ static inline int calculate_message_bytes(u8 status)
58 return -EINVAL; 58 return -EINVAL;
59} 59}
60 60
61static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf) 61static int fill_message(struct snd_fw_async_midi_port *port,
62 struct snd_rawmidi_substream *substream)
62{ 63{
63 struct snd_tscm *tscm = substream->rmidi->private_data;
64 unsigned int port = substream->number;
65 int i, len, consume; 64 int i, len, consume;
66 u8 *label, *msg; 65 u8 *label, *msg;
67 u8 status; 66 u8 status;
68 67
69 /* The first byte is used for label, the rest for MIDI bytes. */ 68 /* The first byte is used for label, the rest for MIDI bytes. */
70 label = buf; 69 label = port->buf;
71 msg = buf + 1; 70 msg = port->buf + 1;
72 71
73 consume = snd_rawmidi_transmit_peek(substream, msg, 3); 72 consume = snd_rawmidi_transmit_peek(substream, msg, 3);
74 if (consume == 0) 73 if (consume == 0)
75 return 0; 74 return 0;
76 75
77 /* On exclusive message. */ 76 /* On exclusive message. */
78 if (tscm->on_sysex[port]) { 77 if (port->on_sysex) {
79 /* Seek the end of exclusives. */ 78 /* Seek the end of exclusives. */
80 for (i = 0; i < consume; ++i) { 79 for (i = 0; i < consume; ++i) {
81 if (msg[i] == 0xf7) { 80 if (msg[i] == 0xf7) {
82 tscm->on_sysex[port] = false; 81 port->on_sysex = false;
83 break; 82 break;
84 } 83 }
85 } 84 }
86 85
87 /* At the end of exclusive message, use label 0x07. */ 86 /* At the end of exclusive message, use label 0x07. */
88 if (!tscm->on_sysex[port]) { 87 if (!port->on_sysex) {
89 consume = i + 1; 88 consume = i + 1;
90 *label = (port << 4) | 0x07; 89 *label = (substream->number << 4) | 0x07;
91 /* During exclusive message, use label 0x04. */ 90 /* During exclusive message, use label 0x04. */
92 } else if (consume == 3) { 91 } else if (consume == 3) {
93 *label = (port << 4) | 0x04; 92 *label = (substream->number << 4) | 0x04;
94 /* We need to fill whole 3 bytes. Go to next change. */ 93 /* We need to fill whole 3 bytes. Go to next change. */
95 } else { 94 } else {
96 return 0; 95 return 0;
@@ -101,12 +100,12 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
101 /* The beginning of exclusives. */ 100 /* The beginning of exclusives. */
102 if (msg[0] == 0xf0) { 101 if (msg[0] == 0xf0) {
103 /* Transfer it in next chance in another condition. */ 102 /* Transfer it in next chance in another condition. */
104 tscm->on_sysex[port] = true; 103 port->on_sysex = true;
105 return 0; 104 return 0;
106 } else { 105 } else {
107 /* On running-status. */ 106 /* On running-status. */
108 if ((msg[0] & 0x80) != 0x80) 107 if ((msg[0] & 0x80) != 0x80)
109 status = tscm->running_status[port]; 108 status = port->running_status;
110 else 109 else
111 status = msg[0]; 110 status = msg[0];
112 111
@@ -124,18 +123,18 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
124 123
125 msg[2] = msg[1]; 124 msg[2] = msg[1];
126 msg[1] = msg[0]; 125 msg[1] = msg[0];
127 msg[0] = tscm->running_status[port]; 126 msg[0] = port->running_status;
128 } else { 127 } else {
129 /* Enough MIDI bytes were not retrieved. */ 128 /* Enough MIDI bytes were not retrieved. */
130 if (consume < len) 129 if (consume < len)
131 return 0; 130 return 0;
132 consume = len; 131 consume = len;
133 132
134 tscm->running_status[port] = msg[0]; 133 port->running_status = msg[0];
135 } 134 }
136 } 135 }
137 136
138 *label = (port << 4) | (msg[0] >> 4); 137 *label = (substream->number << 4) | (msg[0] >> 4);
139 } 138 }
140 139
141 if (len > 0 && len < 3) 140 if (len > 0 && len < 3)
@@ -144,6 +143,106 @@ static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)
144 return consume; 143 return consume;
145} 144}
146 145
146static void async_midi_port_callback(struct fw_card *card, int rcode,
147 void *data, size_t length,
148 void *callback_data)
149{
150 struct snd_fw_async_midi_port *port = callback_data;
151 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
152
153 /* This port is closed. */
154 if (substream == NULL)
155 return;
156
157 if (rcode == RCODE_COMPLETE)
158 snd_rawmidi_transmit_ack(substream, port->consume_bytes);
159 else if (!rcode_is_permanent_error(rcode))
160 /* To start next transaction immediately for recovery. */
161 port->next_ktime = 0;
162 else
163 /* Don't continue processing. */
164 port->error = true;
165
166 port->idling = true;
167
168 if (!snd_rawmidi_transmit_empty(substream))
169 schedule_work(&port->work);
170}
171
172static void midi_port_work(struct work_struct *work)
173{
174 struct snd_fw_async_midi_port *port =
175 container_of(work, struct snd_fw_async_midi_port, work);
176 struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);
177 int generation;
178
179 /* Under transacting or error state. */
180 if (!port->idling || port->error)
181 return;
182
183 /* Nothing to do. */
184 if (substream == NULL || snd_rawmidi_transmit_empty(substream))
185 return;
186
187 /* Do it in next chance. */
188 if (ktime_after(port->next_ktime, ktime_get())) {
189 schedule_work(&port->work);
190 return;
191 }
192
193 /*
194 * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().
195 * Later, snd_rawmidi_transmit_ack() is called.
196 */
197 memset(port->buf, 0, 4);
198 port->consume_bytes = fill_message(port, substream);
199 if (port->consume_bytes <= 0) {
200 /* Do it in next chance, immediately. */
201 if (port->consume_bytes == 0) {
202 port->next_ktime = 0;
203 schedule_work(&port->work);
204 } else {
205 /* Fatal error. */
206 port->error = true;
207 }
208 return;
209 }
210
211 /* Set interval to next transaction. */
212 port->next_ktime = ktime_add_ns(ktime_get(),
213 port->consume_bytes * 8 * NSEC_PER_SEC / 31250);
214
215 /* Start this transaction. */
216 port->idling = false;
217
218 /*
219 * In Linux FireWire core, when generation is updated with memory
220 * barrier, node id has already been updated. In this module, After
221 * this smp_rmb(), load/store instructions to memory are completed.
222 * Thus, both of generation and node id are available with recent
223 * values. This is a light-serialization solution to handle bus reset
224 * events on IEEE 1394 bus.
225 */
226 generation = port->parent->generation;
227 smp_rmb();
228
229 fw_send_request(port->parent->card, &port->transaction,
230 TCODE_WRITE_QUADLET_REQUEST,
231 port->parent->node_id, generation,
232 port->parent->max_speed,
233 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD,
234 port->buf, 4, async_midi_port_callback,
235 port);
236}
237
238void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port)
239{
240 port->idling = true;
241 port->error = false;
242 port->running_status = 0;
243 port->on_sysex = false;
244}
245
147static void handle_midi_tx(struct fw_card *card, struct fw_request *request, 246static void handle_midi_tx(struct fw_card *card, struct fw_request *request,
148 int tcode, int destination, int source, 247 int tcode, int destination, int source,
149 int generation, unsigned long long offset, 248 int generation, unsigned long long offset,
@@ -219,12 +318,9 @@ int snd_tscm_transaction_register(struct snd_tscm *tscm)
219 goto error; 318 goto error;
220 319
221 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) { 320 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) {
222 err = snd_fw_async_midi_port_init( 321 tscm->out_ports[i].parent = fw_parent_device(tscm->unit);
223 &tscm->out_ports[i], tscm->unit, 322 tscm->out_ports[i].next_ktime = 0;
224 TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD, 323 INIT_WORK(&tscm->out_ports[i].work, midi_port_work);
225 4, fill_message);
226 if (err < 0)
227 goto error;
228 } 324 }
229 325
230 return err; 326 return err;
@@ -275,7 +371,6 @@ int snd_tscm_transaction_reregister(struct snd_tscm *tscm)
275void snd_tscm_transaction_unregister(struct snd_tscm *tscm) 371void snd_tscm_transaction_unregister(struct snd_tscm *tscm)
276{ 372{
277 __be32 reg; 373 __be32 reg;
278 unsigned int i;
279 374
280 if (tscm->async_handler.callback_data == NULL) 375 if (tscm->async_handler.callback_data == NULL)
281 return; 376 return;
@@ -302,7 +397,4 @@ void snd_tscm_transaction_unregister(struct snd_tscm *tscm)
302 397
303 fw_core_remove_address_handler(&tscm->async_handler); 398 fw_core_remove_address_handler(&tscm->async_handler);
304 tscm->async_handler.callback_data = NULL; 399 tscm->async_handler.callback_data = NULL;
305
306 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++)
307 snd_fw_async_midi_port_destroy(&tscm->out_ports[i]);
308} 400}
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index d3cd4065722b..08ecfae5c584 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -45,6 +45,23 @@ struct snd_tscm_spec {
45#define TSCM_MIDI_IN_PORT_MAX 4 45#define TSCM_MIDI_IN_PORT_MAX 4
46#define TSCM_MIDI_OUT_PORT_MAX 4 46#define TSCM_MIDI_OUT_PORT_MAX 4
47 47
48struct 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
48struct snd_tscm { 65struct snd_tscm {
49 struct snd_card *card; 66 struct snd_card *card;
50 struct fw_unit *unit; 67 struct fw_unit *unit;
@@ -72,8 +89,6 @@ struct snd_tscm {
72 89
73 /* For MIDI message outgoing transactions. */ 90 /* For MIDI message outgoing transactions. */
74 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX]; 91 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX];
75 u8 running_status[TSCM_MIDI_OUT_PORT_MAX];
76 bool on_sysex[TSCM_MIDI_OUT_PORT_MAX];
77}; 92};
78 93
79#define TSCM_ADDR_BASE 0xffff00000000ull 94#define TSCM_ADDR_BASE 0xffff00000000ull
@@ -131,6 +146,26 @@ void snd_tscm_stream_lock_changed(struct snd_tscm *tscm);
131int snd_tscm_stream_lock_try(struct snd_tscm *tscm); 146int snd_tscm_stream_lock_try(struct snd_tscm *tscm);
132void snd_tscm_stream_lock_release(struct snd_tscm *tscm); 147void snd_tscm_stream_lock_release(struct snd_tscm *tscm);
133 148
149void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port);
150
151static inline void
152snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
153 struct snd_rawmidi_substream *substream)
154{
155 if (!port->error) {
156 port->substream = substream;
157 schedule_work(&port->work);
158 }
159}
160
161static inline void
162snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
163{
164 port->substream = NULL;
165 cancel_work_sync(&port->work);
166 port->error = false;
167}
168
134int snd_tscm_transaction_register(struct snd_tscm *tscm); 169int snd_tscm_transaction_register(struct snd_tscm *tscm);
135int snd_tscm_transaction_reregister(struct snd_tscm *tscm); 170int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
136void snd_tscm_transaction_unregister(struct snd_tscm *tscm); 171void snd_tscm_transaction_unregister(struct snd_tscm *tscm);
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
index 261469188566..84f3b8168716 100644
--- a/sound/hda/ext/hdac_ext_controller.c
+++ b/sound/hda/ext/hdac_ext_controller.c
@@ -171,7 +171,7 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
171{ 171{
172 int timeout; 172 int timeout;
173 u32 val; 173 u32 val;
174 int mask = (1 << AZX_MLCTL_CPA); 174 int mask = (1 << AZX_MLCTL_CPA_SHIFT);
175 175
176 udelay(3); 176 udelay(3);
177 timeout = 150; 177 timeout = 150;
@@ -179,10 +179,10 @@ static int check_hdac_link_power_active(struct hdac_ext_link *link, bool enable)
179 do { 179 do {
180 val = readl(link->ml_addr + AZX_REG_ML_LCTL); 180 val = readl(link->ml_addr + AZX_REG_ML_LCTL);
181 if (enable) { 181 if (enable) {
182 if (((val & mask) >> AZX_MLCTL_CPA)) 182 if (((val & mask) >> AZX_MLCTL_CPA_SHIFT))
183 return 0; 183 return 0;
184 } else { 184 } else {
185 if (!((val & mask) >> AZX_MLCTL_CPA)) 185 if (!((val & mask) >> AZX_MLCTL_CPA_SHIFT))
186 return 0; 186 return 0;
187 } 187 }
188 udelay(3); 188 udelay(3);
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 043065867656..d15b653de0bf 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -272,7 +272,7 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
272 272
273 /* Lets walk the linked capabilities list */ 273 /* Lets walk the linked capabilities list */
274 do { 274 do {
275 cur_cap = _snd_hdac_chip_read(l, bus, offset); 275 cur_cap = _snd_hdac_chip_readl(bus, offset);
276 276
277 dev_dbg(bus->dev, "Capability version: 0x%x\n", 277 dev_dbg(bus->dev, "Capability version: 0x%x\n",
278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF); 278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index c6994ebb4567..e1472c7ab6c1 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -555,12 +555,12 @@ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
555 555
556 if (!reg) 556 if (!reg)
557 reg = AZX_REG_SSYNC; 557 reg = AZX_REG_SSYNC;
558 val = _snd_hdac_chip_read(l, bus, reg); 558 val = _snd_hdac_chip_readl(bus, reg);
559 if (set) 559 if (set)
560 val |= streams; 560 val |= streams;
561 else 561 else
562 val &= ~streams; 562 val &= ~streams;
563 _snd_hdac_chip_write(l, bus, reg, val); 563 _snd_hdac_chip_writel(bus, reg, val);
564} 564}
565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger); 565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);
566 566
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index e2cf508841b1..81cf26fa28d6 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -742,7 +742,7 @@ int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device)
742 742
743 pcm->private_data = chip; 743 pcm->private_data = chip;
744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
745 sprintf(pcm->name, snd_es1688_chip_id(chip)); 745 strcpy(pcm->name, snd_es1688_chip_id(chip));
746 chip->pcm = pcm; 746 chip->pcm = pcm;
747 747
748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 92b819e4f729..34bbc2e730a6 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1339,7 +1339,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
1339 rate = snd_ali_get_spdif_in_rate(codec); 1339 rate = snd_ali_get_spdif_in_rate(codec);
1340 if (rate == 0) { 1340 if (rate == 0) {
1341 dev_warn(codec->card->dev, 1341 dev_warn(codec->card->dev,
1342 "ali_capture_preapre: spdif rate detect err!\n"); 1342 "ali_capture_prepare: spdif rate detect err!\n");
1343 rate = 48000; 1343 rate = 48000;
1344 } 1344 }
1345 spin_lock_irq(&codec->reg_lock); 1345 spin_lock_irq(&codec->reg_lock);
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index ab0f87312911..7a4558a70fb9 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -846,7 +846,7 @@ snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
846 return changed; 846 return changed;
847} 847}
848 848
849static struct snd_kcontrol_new vortex_a3d_kcontrol = { 849static const struct snd_kcontrol_new vortex_a3d_kcontrol = {
850 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 850 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
851 .name = "Playback PCM advanced processing", 851 .name = "Playback PCM advanced processing",
852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index e1af24f87566..c308a4f70550 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2279,6 +2279,9 @@ vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2279 } else { 2279 } else {
2280 int src[2], mix[2]; 2280 int src[2], mix[2];
2281 2281
2282 if (nr_ch < 1)
2283 return -EINVAL;
2284
2282 /* Get SRC and MIXER hardware resources. */ 2285 /* Get SRC and MIXER hardware resources. */
2283 for (i = 0; i < nr_ch; i++) { 2286 for (i = 0; i < nr_ch; i++) {
2284 if ((mix[i] = 2287 if ((mix[i] =
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 9585c5c63b96..b566b44e4da7 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -757,7 +757,7 @@ snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol,
757 return 1; /* Allways changes */ 757 return 1; /* Allways changes */
758} 758}
759 759
760static struct snd_kcontrol_new vortex_eqtoggle_kcontrol = { 760static const struct snd_kcontrol_new vortex_eqtoggle_kcontrol = {
761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
762 .name = "EQ Enable", 762 .name = "EQ Enable",
763 .index = 0, 763 .index = 0,
@@ -815,7 +815,7 @@ snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon
815 return changed; 815 return changed;
816} 816}
817 817
818static struct snd_kcontrol_new vortex_eq_kcontrol = { 818static const struct snd_kcontrol_new vortex_eq_kcontrol = {
819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
820 .name = " .", 820 .name = " .",
821 .index = 0, 821 .index = 0,
@@ -855,7 +855,7 @@ snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
855 return 0; 855 return 0;
856} 856}
857 857
858static struct snd_kcontrol_new vortex_levels_kcontrol = { 858static const struct snd_kcontrol_new vortex_levels_kcontrol = {
859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
860 .name = "EQ Peaks", 860 .name = "EQ Peaks",
861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index df5741a78fd2..335979a753fe 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -601,7 +601,7 @@ static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
601 601
602static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); 602static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
603 603
604static struct snd_kcontrol_new snd_vortex_pcm_vol = { 604static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
606 .name = "PCM Playback Volume", 606 .name = "PCM Playback Volume",
607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 57bbb87d0c62..8356180bfe0e 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -202,7 +202,7 @@ static const struct snd_pcm_ops snd_aw2_capture_ops = {
202 .pointer = snd_aw2_pcm_pointer_capture, 202 .pointer = snd_aw2_pcm_pointer_capture,
203}; 203};
204 204
205static struct snd_kcontrol_new aw2_control = { 205static const struct snd_kcontrol_new aw2_control = {
206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
207 .name = "PCM Capture Route", 207 .name = "PCM Capture Route",
208 .index = 0, 208 .index = 0,
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index f2c0709d7441..099efb046b1c 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -598,7 +598,7 @@ static int snd_bt87x_capture_volume_put(struct snd_kcontrol *kcontrol,
598 return changed; 598 return changed;
599} 599}
600 600
601static struct snd_kcontrol_new snd_bt87x_capture_volume = { 601static const struct snd_kcontrol_new snd_bt87x_capture_volume = {
602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
603 .name = "Capture Volume", 603 .name = "Capture Volume",
604 .info = snd_bt87x_capture_volume_info, 604 .info = snd_bt87x_capture_volume_info,
@@ -634,7 +634,7 @@ static int snd_bt87x_capture_boost_put(struct snd_kcontrol *kcontrol,
634 return changed; 634 return changed;
635} 635}
636 636
637static struct snd_kcontrol_new snd_bt87x_capture_boost = { 637static const struct snd_kcontrol_new snd_bt87x_capture_boost = {
638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
639 .name = "Capture Boost", 639 .name = "Capture Boost",
640 .info = snd_bt87x_capture_boost_info, 640 .info = snd_bt87x_capture_boost_info,
@@ -676,7 +676,7 @@ static int snd_bt87x_capture_source_put(struct snd_kcontrol *kcontrol,
676 return changed; 676 return changed;
677} 677}
678 678
679static struct snd_kcontrol_new snd_bt87x_capture_source = { 679static const struct snd_kcontrol_new snd_bt87x_capture_source = {
680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
681 .name = "Capture Source", 681 .name = "Capture Source",
682 .info = snd_bt87x_capture_source_info, 682 .info = snd_bt87x_capture_source_info,
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 025805cba779..b4d3415331f6 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -301,7 +301,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
301 return change; 301 return change;
302} 302}
303 303
304static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in = 304static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
305{ 305{
306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
307 .name = "Shared Mic/Line in Capture Switch", 307 .name = "Shared Mic/Line in Capture Switch",
@@ -310,7 +310,7 @@ static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
310 .put = snd_ca0106_capture_mic_line_in_put 310 .put = snd_ca0106_capture_mic_line_in_put
311}; 311};
312 312
313static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out = 313static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
314{ 314{
315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
316 .name = "Shared Line in/Side out Capture Switch", 316 .name = "Shared Line in/Side out Capture Switch",
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index aeedc270ed9b..227c9d3802b8 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1045,7 +1045,7 @@ static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
1045 return change; 1045 return change;
1046} 1046}
1047 1047
1048static struct snd_kcontrol_new snd_cmipci_spdif_default = 1048static const struct snd_kcontrol_new snd_cmipci_spdif_default =
1049{ 1049{
1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1072,7 +1072,7 @@ static int snd_cmipci_spdif_mask_get(struct snd_kcontrol *kcontrol,
1072 return 0; 1072 return 0;
1073} 1073}
1074 1074
1075static struct snd_kcontrol_new snd_cmipci_spdif_mask = 1075static const struct snd_kcontrol_new snd_cmipci_spdif_mask =
1076{ 1076{
1077 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1077 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1119,7 +1119,7 @@ static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
1119 return change; 1119 return change;
1120} 1120}
1121 1121
1122static struct snd_kcontrol_new snd_cmipci_spdif_stream = 1122static const struct snd_kcontrol_new snd_cmipci_spdif_stream =
1123{ 1123{
1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index fa7c51684dd2..f870697aca67 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1055,7 +1055,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
1055 1055
1056static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); 1056static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0);
1057 1057
1058static struct snd_kcontrol_new snd_cs4281_fm_vol = 1058static const struct snd_kcontrol_new snd_cs4281_fm_vol =
1059{ 1059{
1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1061 .name = "Synth Playback Volume", 1061 .name = "Synth Playback Volume",
@@ -1066,7 +1066,7 @@ static struct snd_kcontrol_new snd_cs4281_fm_vol =
1066 .tlv = { .p = db_scale_dsp }, 1066 .tlv = { .p = db_scale_dsp },
1067}; 1067};
1068 1068
1069static struct snd_kcontrol_new snd_cs4281_pcm_vol = 1069static const struct snd_kcontrol_new snd_cs4281_pcm_vol =
1070{ 1070{
1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1072 .name = "PCM Stream Playback Volume", 1072 .name = "PCM Stream Playback Volume",
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 937071760bc4..d15ecf9febbf 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1039,7 +1039,7 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
1039 1039
1040#ifdef ECHOCARD_HAS_LINE_OUT_GAIN 1040#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
1041/* On the Mia this one controls the line-out volume */ 1041/* On the Mia this one controls the line-out volume */
1042static struct snd_kcontrol_new snd_echo_line_output_gain = { 1042static const struct snd_kcontrol_new snd_echo_line_output_gain = {
1043 .name = "Line Playback Volume", 1043 .name = "Line Playback Volume",
1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1050,7 +1050,7 @@ static struct snd_kcontrol_new snd_echo_line_output_gain = {
1050 .tlv = {.p = db_scale_output_gain}, 1050 .tlv = {.p = db_scale_output_gain},
1051}; 1051};
1052#else 1052#else
1053static struct snd_kcontrol_new snd_echo_pcm_output_gain = { 1053static const struct snd_kcontrol_new snd_echo_pcm_output_gain = {
1054 .name = "PCM Playback Volume", 1054 .name = "PCM Playback Volume",
1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1120,7 +1120,7 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
1120 1120
1121static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); 1121static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
1122 1122
1123static struct snd_kcontrol_new snd_echo_line_input_gain = { 1123static const struct snd_kcontrol_new snd_echo_line_input_gain = {
1124 .name = "Line Capture Volume", 1124 .name = "Line Capture Volume",
1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, 1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1184,7 +1184,7 @@ static int snd_echo_output_nominal_put(struct snd_kcontrol *kcontrol,
1184 return changed; 1184 return changed;
1185} 1185}
1186 1186
1187static struct snd_kcontrol_new snd_echo_output_nominal_level = { 1187static const struct snd_kcontrol_new snd_echo_output_nominal_level = {
1188 .name = "Line Playback Switch (-10dBV)", 1188 .name = "Line Playback Switch (-10dBV)",
1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1190 .info = snd_echo_output_nominal_info, 1190 .info = snd_echo_output_nominal_info,
@@ -1250,7 +1250,7 @@ static int snd_echo_input_nominal_put(struct snd_kcontrol *kcontrol,
1250 return changed; 1250 return changed;
1251} 1251}
1252 1252
1253static struct snd_kcontrol_new snd_echo_intput_nominal_level = { 1253static const struct snd_kcontrol_new snd_echo_intput_nominal_level = {
1254 .name = "Line Capture Switch (-10dBV)", 1254 .name = "Line Capture Switch (-10dBV)",
1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1256 .info = snd_echo_input_nominal_info, 1256 .info = snd_echo_input_nominal_info,
@@ -1477,7 +1477,7 @@ static int snd_echo_digital_mode_put(struct snd_kcontrol *kcontrol,
1477 return changed; 1477 return changed;
1478} 1478}
1479 1479
1480static struct snd_kcontrol_new snd_echo_digital_mode_switch = { 1480static const struct snd_kcontrol_new snd_echo_digital_mode_switch = {
1481 .name = "Digital mode Switch", 1481 .name = "Digital mode Switch",
1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1483 .info = snd_echo_digital_mode_info, 1483 .info = snd_echo_digital_mode_info,
@@ -1527,7 +1527,7 @@ static int snd_echo_spdif_mode_put(struct snd_kcontrol *kcontrol,
1527 return 0; 1527 return 0;
1528} 1528}
1529 1529
1530static struct snd_kcontrol_new snd_echo_spdif_mode_switch = { 1530static const struct snd_kcontrol_new snd_echo_spdif_mode_switch = {
1531 .name = "S/PDIF mode Switch", 1531 .name = "S/PDIF mode Switch",
1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1533 .info = snd_echo_spdif_mode_info, 1533 .info = snd_echo_spdif_mode_info,
@@ -1600,7 +1600,7 @@ static int snd_echo_clock_source_put(struct snd_kcontrol *kcontrol,
1600 return changed; 1600 return changed;
1601} 1601}
1602 1602
1603static struct snd_kcontrol_new snd_echo_clock_source_switch = { 1603static const struct snd_kcontrol_new snd_echo_clock_source_switch = {
1604 .name = "Sample Clock Source", 1604 .name = "Sample Clock Source",
1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1606 .info = snd_echo_clock_source_info, 1606 .info = snd_echo_clock_source_info,
@@ -1643,7 +1643,7 @@ static int snd_echo_phantom_power_put(struct snd_kcontrol *kcontrol,
1643 return changed; 1643 return changed;
1644} 1644}
1645 1645
1646static struct snd_kcontrol_new snd_echo_phantom_power_switch = { 1646static const struct snd_kcontrol_new snd_echo_phantom_power_switch = {
1647 .name = "Phantom power Switch", 1647 .name = "Phantom power Switch",
1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1649 .info = snd_echo_phantom_power_info, 1649 .info = snd_echo_phantom_power_info,
@@ -1686,7 +1686,7 @@ static int snd_echo_automute_put(struct snd_kcontrol *kcontrol,
1686 return changed; 1686 return changed;
1687} 1687}
1688 1688
1689static struct snd_kcontrol_new snd_echo_automute_switch = { 1689static const struct snd_kcontrol_new snd_echo_automute_switch = {
1690 .name = "Digital Capture Switch (automute)", 1690 .name = "Digital Capture Switch (automute)",
1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1692 .info = snd_echo_automute_info, 1692 .info = snd_echo_automute_info,
@@ -1713,7 +1713,7 @@ static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
1713 return 1; 1713 return 1;
1714} 1714}
1715 1715
1716static struct snd_kcontrol_new snd_echo_vumeters_switch = { 1716static const struct snd_kcontrol_new snd_echo_vumeters_switch = {
1717 .name = "VU-meters Switch", 1717 .name = "VU-meters Switch",
1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE, 1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
@@ -1751,7 +1751,7 @@ static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
1751 return 0; 1751 return 0;
1752} 1752}
1753 1753
1754static struct snd_kcontrol_new snd_echo_vumeters = { 1754static const struct snd_kcontrol_new snd_echo_vumeters = {
1755 .name = "VU-meters", 1755 .name = "VU-meters",
1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1757 .access = SNDRV_CTL_ELEM_ACCESS_READ | 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ |
@@ -1804,7 +1804,7 @@ static int snd_echo_channels_info_get(struct snd_kcontrol *kcontrol,
1804 return 0; 1804 return 0;
1805} 1805}
1806 1806
1807static struct snd_kcontrol_new snd_echo_channels_info = { 1807static const struct snd_kcontrol_new snd_echo_channels_info = {
1808 .name = "Channels info", 1808 .name = "Channels info",
1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, 1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 32842734ada6..77a4413f4564 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1112,7 +1112,7 @@ static int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
1112 return change; 1112 return change;
1113} 1113}
1114 1114
1115static struct snd_kcontrol_new snd_emu10k1x_shared_spdif = 1115static const struct snd_kcontrol_new snd_emu10k1x_shared_spdif =
1116{ 1116{
1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1118 .name = "Analog/Digital Output Jack", 1118 .name = "Analog/Digital Output Jack",
@@ -1171,7 +1171,7 @@ static int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
1171 return change; 1171 return change;
1172} 1172}
1173 1173
1174static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control = 1174static const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
1175{ 1175{
1176 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1176 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1181,7 +1181,7 @@ static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
1181 .get = snd_emu10k1x_spdif_get_mask 1181 .get = snd_emu10k1x_spdif_get_mask
1182}; 1182};
1183 1183
1184static struct snd_kcontrol_new snd_emu10k1x_spdif_control = 1184static const struct snd_kcontrol_new snd_emu10k1x_spdif_control =
1185{ 1185{
1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 076b117009c5..b2219a73c17c 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -795,7 +795,7 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
795 return change; 795 return change;
796} 796}
797 797
798static struct snd_kcontrol_new snd_emu1010_internal_clock = 798static const struct snd_kcontrol_new snd_emu1010_internal_clock =
799{ 799{
800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -847,7 +847,7 @@ static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol,
847 return change; 847 return change;
848} 848}
849 849
850static struct snd_kcontrol_new snd_emu1010_optical_out = { 850static const struct snd_kcontrol_new snd_emu1010_optical_out = {
851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
853 .name = "Optical Output Mode", 853 .name = "Optical Output Mode",
@@ -898,7 +898,7 @@ static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol,
898 return change; 898 return change;
899} 899}
900 900
901static struct snd_kcontrol_new snd_emu1010_optical_in = { 901static const struct snd_kcontrol_new snd_emu1010_optical_in = {
902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "Optical Input Mode", 904 .name = "Optical Input Mode",
@@ -978,7 +978,7 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
978 return change; 978 return change;
979} 979}
980 980
981static struct snd_kcontrol_new snd_audigy_i2c_capture_source = 981static const struct snd_kcontrol_new snd_audigy_i2c_capture_source =
982{ 982{
983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
984 .name = "Capture Source", 984 .name = "Capture Source",
@@ -1177,7 +1177,7 @@ static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
1177 return change; 1177 return change;
1178} 1178}
1179 1179
1180static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = 1180static const struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
1181{ 1181{
1182 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1182 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1187,7 +1187,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
1187 .get = snd_emu10k1_spdif_get_mask 1187 .get = snd_emu10k1_spdif_get_mask
1188}; 1188};
1189 1189
1190static struct snd_kcontrol_new snd_emu10k1_spdif_control = 1190static const struct snd_kcontrol_new snd_emu10k1_spdif_control =
1191{ 1191{
1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1293,7 +1293,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
1293 return change; 1293 return change;
1294} 1294}
1295 1295
1296static struct snd_kcontrol_new snd_emu10k1_send_routing_control = 1296static const struct snd_kcontrol_new snd_emu10k1_send_routing_control =
1297{ 1297{
1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1364,7 +1364,7 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
1364 return change; 1364 return change;
1365} 1365}
1366 1366
1367static struct snd_kcontrol_new snd_emu10k1_send_volume_control = 1367static const struct snd_kcontrol_new snd_emu10k1_send_volume_control =
1368{ 1368{
1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1429,7 +1429,7 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
1429 return change; 1429 return change;
1430} 1430}
1431 1431
1432static struct snd_kcontrol_new snd_emu10k1_attn_control = 1432static const struct snd_kcontrol_new snd_emu10k1_attn_control =
1433{ 1433{
1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1501,7 +1501,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
1501 return change; 1501 return change;
1502} 1502}
1503 1503
1504static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control = 1504static const struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
1505{ 1505{
1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1568,7 +1568,7 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
1568} 1568}
1569 1569
1570 1570
1571static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control = 1571static const struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
1572{ 1572{
1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1626,7 +1626,7 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
1626 return change; 1626 return change;
1627} 1627}
1628 1628
1629static struct snd_kcontrol_new snd_emu10k1_efx_attn_control = 1629static const struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
1630{ 1630{
1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1691,7 +1691,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1691 return change; 1691 return change;
1692} 1692}
1693 1693
1694static struct snd_kcontrol_new snd_emu10k1_shared_spdif = 1694static const struct snd_kcontrol_new snd_emu10k1_shared_spdif =
1695{ 1695{
1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1697 .name = "SB Live Analog/Digital Output Jack", 1697 .name = "SB Live Analog/Digital Output Jack",
@@ -1700,7 +1700,7 @@ static struct snd_kcontrol_new snd_emu10k1_shared_spdif =
1700 .put = snd_emu10k1_shared_spdif_put 1700 .put = snd_emu10k1_shared_spdif_put
1701}; 1701};
1702 1702
1703static struct snd_kcontrol_new snd_audigy_shared_spdif = 1703static const struct snd_kcontrol_new snd_audigy_shared_spdif =
1704{ 1704{
1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1706 .name = "Audigy Analog/Digital Output Jack", 1706 .name = "Audigy Analog/Digital Output Jack",
@@ -1738,7 +1738,7 @@ static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val); 1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
1739} 1739}
1740 1740
1741static struct snd_kcontrol_new snd_audigy_capture_boost = 1741static const struct snd_kcontrol_new snd_audigy_capture_boost =
1742{ 1742{
1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1744 .name = "Mic Extra Boost", 1744 .name = "Mic Extra Boost",
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 37be1e14d756..ef1cf530c929 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1542,7 +1542,7 @@ static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, st
1542 return change; 1542 return change;
1543} 1543}
1544 1544
1545static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = { 1545static const struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = {
1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1547 .name = "Captured FX8010 Outputs", 1547 .name = "Captured FX8010 Outputs",
1548 .info = snd_emu10k1_pcm_efx_voices_mask_info, 1548 .info = snd_emu10k1_pcm_efx_voices_mask_info,
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 164adad91650..5d10349d11ce 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1530,7 +1530,7 @@ static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
1530 return change; 1530 return change;
1531} 1531}
1532 1532
1533static struct snd_kcontrol_new snd_ens1373_rear = 1533static const struct snd_kcontrol_new snd_ens1373_rear =
1534{ 1534{
1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1536 .name = "AC97 2ch->4ch Copy Switch", 1536 .name = "AC97 2ch->4ch Copy Switch",
@@ -1575,7 +1575,7 @@ static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
1575 return changed; 1575 return changed;
1576} 1576}
1577 1577
1578static struct snd_kcontrol_new snd_ens1373_line = 1578static const struct snd_kcontrol_new snd_ens1373_line =
1579{ 1579{
1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1581 .name = "Line In->Rear Out Switch", 1581 .name = "Line In->Rear Out Switch",
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index a03cf68d0bcd..d3ea73171a3d 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
580 has_multiple_pins = 1; 580 has_multiple_pins = 1;
581 if (has_multiple_pins && type == AUTO_PIN_MIC) 581 if (has_multiple_pins && type == AUTO_PIN_MIC)
582 has_multiple_pins &= check_mic_location_need(codec, cfg, input); 582 has_multiple_pins &= check_mic_location_need(codec, cfg, input);
583 has_multiple_pins |= codec->force_pin_prefix;
583 return hda_get_input_pin_label(codec, &cfg->inputs[input], 584 return hda_get_input_pin_label(codec, &cfg->inputs[input],
584 cfg->inputs[input].pin, 585 cfg->inputs[input].pin,
585 has_multiple_pins); 586 has_multiple_pins);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8fd745cb3f36..70bb365a08d2 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1965,7 +1965,7 @@ static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
1965 return 1; 1965 return 1;
1966} 1966}
1967 1967
1968static struct snd_kcontrol_new vmaster_mute_mode = { 1968static const struct snd_kcontrol_new vmaster_mute_mode = {
1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1970 .name = "Mute-LED Mode", 1970 .name = "Mute-LED Mode",
1971 .info = vmaster_mute_mode_info, 1971 .info = vmaster_mute_mode_info,
@@ -2705,7 +2705,7 @@ static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
2705 return 0; 2705 return 0;
2706} 2706}
2707 2707
2708static struct snd_kcontrol_new spdif_share_sw = { 2708static const struct snd_kcontrol_new spdif_share_sw = {
2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2710 .name = "IEC958 Default PCM Playback Switch", 2710 .name = "IEC958 Default PCM Playback Switch",
2711 .info = snd_ctl_boolean_mono_info, 2711 .info = snd_ctl_boolean_mono_info,
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f17f25245e52..d6fb2d5d01a7 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -256,6 +256,7 @@ struct hda_codec {
256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ 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 */ 257 unsigned int power_save_node:1; /* advanced PM for each widget */
258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */ 258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
259 unsigned int force_pin_prefix:1; /* Add location prefix */
259#ifdef CONFIG_PM 260#ifdef CONFIG_PM
260 unsigned long power_on_acct; 261 unsigned long power_on_acct;
261 unsigned long power_off_acct; 262 unsigned long power_off_acct;
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index e7c8f4f076d5..2842c82363c0 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect"); 196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
197 if (val >= 0) 197 if (val >= 0)
198 spec->suppress_hp_mic_detect = !val; 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;
199 202
200 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) 203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
201 spec->mixer_nid = val; 204 spec->mixer_nid = val;
@@ -1125,6 +1128,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1125 1128
1126 *index = 0; 1129 *index = 0;
1127 if (cfg->line_outs == 1 && !spec->multi_ios && 1130 if (cfg->line_outs == 1 && !spec->multi_ios &&
1131 !codec->force_pin_prefix &&
1128 !cfg->hp_outs && !cfg->speaker_outs) 1132 !cfg->hp_outs && !cfg->speaker_outs)
1129 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1133 return spec->vmaster_mute.hook ? "PCM" : "Master";
1130 1134
@@ -1132,6 +1136,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1132 * use it master (or "PCM" if a vmaster hook is present) 1136 * use it master (or "PCM" if a vmaster hook is present)
1133 */ 1137 */
1134 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid && 1138 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
1139 !codec->force_pin_prefix &&
1135 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) 1140 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
1136 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1141 return spec->vmaster_mute.hook ? "PCM" : "Master";
1137 1142
@@ -5031,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5031 } 5036 }
5032 5037
5033 /* if we have no master control, let's create it */ 5038 /* if we have no master control, let's create it */
5034 if (!spec->no_analog && 5039 if (!spec->no_analog && !spec->suppress_vmaster &&
5035 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 5040 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
5036 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 5041 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
5037 spec->vmaster_tlv, slave_pfxs, 5042 spec->vmaster_tlv, slave_pfxs,
@@ -5039,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5039 if (err < 0) 5044 if (err < 0)
5040 return err; 5045 return err;
5041 } 5046 }
5042 if (!spec->no_analog && 5047 if (!spec->no_analog && !spec->suppress_vmaster &&
5043 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 5048 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
5044 err = __snd_hda_add_vmaster(codec, "Master Playback Switch", 5049 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
5045 NULL, slave_pfxs, 5050 NULL, slave_pfxs,
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index f66fc7e25e07..61772317de46 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -229,6 +229,7 @@ struct hda_gen_spec {
229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */ 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 */ 230 unsigned int power_down_unused:1; /* power down unused widgets */
231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */ 231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */
232 unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
232 233
233 /* other internal flags */ 234 /* other internal flags */
234 unsigned int no_analog:1; /* digital I/O only */ 235 unsigned int no_analog:1; /* digital I/O only */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c8256a89375a..b786fbab029f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -77,6 +77,7 @@ enum {
77 POS_FIX_POSBUF, 77 POS_FIX_POSBUF,
78 POS_FIX_VIACOMBO, 78 POS_FIX_VIACOMBO,
79 POS_FIX_COMBO, 79 POS_FIX_COMBO,
80 POS_FIX_SKL,
80}; 81};
81 82
82/* Defines for ATI HD Audio support in SB450 south bridge */ 83/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -148,7 +149,7 @@ module_param_array(model, charp, NULL, 0444);
148MODULE_PARM_DESC(model, "Use the given board model."); 149MODULE_PARM_DESC(model, "Use the given board model.");
149module_param_array(position_fix, int, NULL, 0444); 150module_param_array(position_fix, int, NULL, 0444);
150MODULE_PARM_DESC(position_fix, "DMA pointer read method." 151MODULE_PARM_DESC(position_fix, "DMA pointer read method."
151 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO)."); 152 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+).");
152module_param_array(bdl_pos_adj, int, NULL, 0644); 153module_param_array(bdl_pos_adj, int, NULL, 0644);
153MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 154MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
154module_param_array(probe_mask, int, NULL, 0444); 155module_param_array(probe_mask, int, NULL, 0444);
@@ -369,8 +370,10 @@ enum {
369#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71) 370#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_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
371#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) 372#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
373#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)
372#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \ 374#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
373 IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) 375 IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \
376 IS_GLK(pci)
374 377
375static char *driver_short_names[] = { 378static char *driver_short_names[] = {
376 [AZX_DRIVER_ICH] = "HDA Intel", 379 [AZX_DRIVER_ICH] = "HDA Intel",
@@ -534,9 +537,101 @@ static void bxt_reduce_dma_latency(struct azx *chip)
534{ 537{
535 u32 val; 538 u32 val;
536 539
537 val = azx_readl(chip, SKL_EM4L); 540 val = azx_readl(chip, VS_EM4L);
538 val &= (0x3 << 20); 541 val &= (0x3 << 20);
539 azx_writel(chip, SKL_EM4L, val); 542 azx_writel(chip, VS_EM4L, val);
543}
544
545/*
546 * ML_LCAP bits:
547 * bit 0: 6 MHz Supported
548 * bit 1: 12 MHz Supported
549 * bit 2: 24 MHz Supported
550 * bit 3: 48 MHz Supported
551 * bit 4: 96 MHz Supported
552 * bit 5: 192 MHz Supported
553 */
554static int intel_get_lctl_scf(struct azx *chip)
555{
556 struct hdac_bus *bus = azx_bus(chip);
557 static int preferred_bits[] = { 2, 3, 1, 4, 5 };
558 u32 val, t;
559 int i;
560
561 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);
562
563 for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {
564 t = preferred_bits[i];
565 if (val & (1 << t))
566 return t;
567 }
568
569 dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");
570 return 0;
571}
572
573static int intel_ml_lctl_set_power(struct azx *chip, int state)
574{
575 struct hdac_bus *bus = azx_bus(chip);
576 u32 val;
577 int timeout;
578
579 /*
580 * the codecs are sharing the first link setting by default
581 * If other links are enabled for stream, they need similar fix
582 */
583 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
584 val &= ~AZX_MLCTL_SPA;
585 val |= state << AZX_MLCTL_SPA_SHIFT;
586 writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
587 /* wait for CPA */
588 timeout = 50;
589 while (timeout) {
590 if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &
591 AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))
592 return 0;
593 timeout--;
594 udelay(10);
595 }
596
597 return -1;
598}
599
600static void intel_init_lctl(struct azx *chip)
601{
602 struct hdac_bus *bus = azx_bus(chip);
603 u32 val;
604 int ret;
605
606 /* 0. check lctl register value is correct or not */
607 val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
608 /* if SCF is already set, let's use it */
609 if ((val & ML_LCTL_SCF_MASK) != 0)
610 return;
611
612 /*
613 * Before operating on SPA, CPA must match SPA.
614 * Any deviation may result in undefined behavior.
615 */
616 if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=
617 ((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))
618 return;
619
620 /* 1. turn link down: set SPA to 0 and wait CPA to 0 */
621 ret = intel_ml_lctl_set_power(chip, 0);
622 udelay(100);
623 if (ret)
624 goto set_spa;
625
626 /* 2. update SCF to select a properly audio clock*/
627 val &= ~ML_LCTL_SCF_MASK;
628 val |= intel_get_lctl_scf(chip);
629 writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
630
631set_spa:
632 /* 4. turn link up: set SPA to 1 and wait CPA to 1 */
633 intel_ml_lctl_set_power(chip, 1);
634 udelay(100);
540} 635}
541 636
542static void hda_intel_init_chip(struct azx *chip, bool full_reset) 637static void hda_intel_init_chip(struct azx *chip, bool full_reset)
@@ -564,6 +659,9 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
564 /* reduce dma latency to avoid noise */ 659 /* reduce dma latency to avoid noise */
565 if (IS_BXT(pci)) 660 if (IS_BXT(pci))
566 bxt_reduce_dma_latency(chip); 661 bxt_reduce_dma_latency(chip);
662
663 if (bus->mlcap != NULL)
664 intel_init_lctl(chip);
567} 665}
568 666
569/* calculate runtime delay from LPIB */ 667/* calculate runtime delay from LPIB */
@@ -815,6 +913,31 @@ static unsigned int azx_via_get_position(struct azx *chip,
815 return bound_pos + mod_dma_pos; 913 return bound_pos + mod_dma_pos;
816} 914}
817 915
916static unsigned int azx_skl_get_dpib_pos(struct azx *chip,
917 struct azx_dev *azx_dev)
918{
919 return _snd_hdac_chip_readl(azx_bus(chip),
920 AZX_REG_VS_SDXDPIB_XBASE +
921 (AZX_REG_VS_SDXDPIB_XINTERVAL *
922 azx_dev->core.index));
923}
924
925/* get the current DMA position with correction on SKL+ chips */
926static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev)
927{
928 /* DPIB register gives a more accurate position for playback */
929 if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
930 return azx_skl_get_dpib_pos(chip, azx_dev);
931
932 /* For capture, we need to read posbuf, but it requires a delay
933 * for the possible boundary overlap; the read of DPIB fetches the
934 * actual posbuf
935 */
936 udelay(20);
937 azx_skl_get_dpib_pos(chip, azx_dev);
938 return azx_get_pos_posbuf(chip, azx_dev);
939}
940
818#ifdef CONFIG_PM 941#ifdef CONFIG_PM
819static DEFINE_MUTEX(card_list_lock); 942static DEFINE_MUTEX(card_list_lock);
820static LIST_HEAD(card_list); 943static LIST_HEAD(card_list);
@@ -1351,6 +1474,7 @@ static int check_position_fix(struct azx *chip, int fix)
1351 case POS_FIX_POSBUF: 1474 case POS_FIX_POSBUF:
1352 case POS_FIX_VIACOMBO: 1475 case POS_FIX_VIACOMBO:
1353 case POS_FIX_COMBO: 1476 case POS_FIX_COMBO:
1477 case POS_FIX_SKL:
1354 return fix; 1478 return fix;
1355 } 1479 }
1356 1480
@@ -1371,6 +1495,10 @@ static int check_position_fix(struct azx *chip, int fix)
1371 dev_dbg(chip->card->dev, "Using LPIB position fix\n"); 1495 dev_dbg(chip->card->dev, "Using LPIB position fix\n");
1372 return POS_FIX_LPIB; 1496 return POS_FIX_LPIB;
1373 } 1497 }
1498 if (IS_SKL_PLUS(chip->pci)) {
1499 dev_dbg(chip->card->dev, "Using SKL position fix\n");
1500 return POS_FIX_SKL;
1501 }
1374 return POS_FIX_AUTO; 1502 return POS_FIX_AUTO;
1375} 1503}
1376 1504
@@ -1382,6 +1510,7 @@ static void assign_position_fix(struct azx *chip, int fix)
1382 [POS_FIX_POSBUF] = azx_get_pos_posbuf, 1510 [POS_FIX_POSBUF] = azx_get_pos_posbuf,
1383 [POS_FIX_VIACOMBO] = azx_via_get_position, 1511 [POS_FIX_VIACOMBO] = azx_via_get_position,
1384 [POS_FIX_COMBO] = azx_get_pos_lpib, 1512 [POS_FIX_COMBO] = azx_get_pos_lpib,
1513 [POS_FIX_SKL] = azx_get_pos_skl,
1385 }; 1514 };
1386 1515
1387 chip->get_position[0] = chip->get_position[1] = callbacks[fix]; 1516 chip->get_position[0] = chip->get_position[1] = callbacks[fix];
@@ -1390,7 +1519,7 @@ static void assign_position_fix(struct azx *chip, int fix)
1390 if (fix == POS_FIX_COMBO) 1519 if (fix == POS_FIX_COMBO)
1391 chip->get_position[1] = NULL; 1520 chip->get_position[1] = NULL;
1392 1521
1393 if (fix == POS_FIX_POSBUF && 1522 if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&
1394 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { 1523 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
1395 chip->get_delay[0] = chip->get_delay[1] = 1524 chip->get_delay[0] = chip->get_delay[1] =
1396 azx_get_delay_from_lpib; 1525 azx_get_delay_from_lpib;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 07a9deb17477..a148176c16a9 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -857,7 +857,7 @@ static int chipio_write_address(struct hda_codec *codec,
857 chip_addx >> 16); 857 chip_addx >> 16);
858 } 858 }
859 859
860 spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx; 860 spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx;
861 861
862 return res; 862 return res;
863} 863}
@@ -882,7 +882,7 @@ static int chipio_write_data(struct hda_codec *codec, unsigned int data)
882 /*If no error encountered, automatically increment the address 882 /*If no error encountered, automatically increment the address
883 as per chip behaviour*/ 883 as per chip behaviour*/
884 spec->curr_chip_addx = (res != -EIO) ? 884 spec->curr_chip_addx = (res != -EIO) ?
885 (spec->curr_chip_addx + 4) : ~0UL; 885 (spec->curr_chip_addx + 4) : ~0U;
886 return res; 886 return res;
887} 887}
888 888
@@ -933,7 +933,7 @@ static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
933 /*If no error encountered, automatically increment the address 933 /*If no error encountered, automatically increment the address
934 as per chip behaviour*/ 934 as per chip behaviour*/
935 spec->curr_chip_addx = (res != -EIO) ? 935 spec->curr_chip_addx = (res != -EIO) ?
936 (spec->curr_chip_addx + 4) : ~0UL; 936 (spec->curr_chip_addx + 4) : ~0U;
937 return res; 937 return res;
938} 938}
939 939
@@ -1168,7 +1168,7 @@ static int dspio_write_multiple(struct hda_codec *codec,
1168 int status = 0; 1168 int status = 0;
1169 unsigned int count; 1169 unsigned int count;
1170 1170
1171 if ((buffer == NULL)) 1171 if (buffer == NULL)
1172 return -EINVAL; 1172 return -EINVAL;
1173 1173
1174 count = 0; 1174 count = 0;
@@ -1210,7 +1210,7 @@ static int dspio_read_multiple(struct hda_codec *codec, unsigned int *buffer,
1210 unsigned int skip_count; 1210 unsigned int skip_count;
1211 unsigned int dummy; 1211 unsigned int dummy;
1212 1212
1213 if ((buffer == NULL)) 1213 if (buffer == NULL)
1214 return -1; 1214 return -1;
1215 1215
1216 count = 0; 1216 count = 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 69266b8ea2ad..e8253737c47a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -52,6 +52,12 @@ struct conexant_spec {
52 bool dc_enable; 52 bool dc_enable;
53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ 53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */
54 struct nid_path *dc_mode_path; 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
55}; 61};
56 62
57 63
@@ -264,6 +270,7 @@ enum {
264 CXT_FIXUP_HP_DOCK, 270 CXT_FIXUP_HP_DOCK,
265 CXT_FIXUP_HP_SPECTRE, 271 CXT_FIXUP_HP_SPECTRE,
266 CXT_FIXUP_HP_GATE_MIC, 272 CXT_FIXUP_HP_GATE_MIC,
273 CXT_FIXUP_MUTE_LED_GPIO,
267}; 274};
268 275
269/* for hda_fixup_thinkpad_acpi() */ 276/* for hda_fixup_thinkpad_acpi() */
@@ -646,6 +653,74 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,
646 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); 653 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16);
647} 654}
648 655
656/* update LED status via GPIO */
657static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask,
658 bool enabled)
659{
660 struct conexant_spec *spec = codec->spec;
661 unsigned int oldval = spec->gpio_led;
662
663 if (spec->mute_led_polarity)
664 enabled = !enabled;
665
666 if (enabled)
667 spec->gpio_led &= ~mask;
668 else
669 spec->gpio_led |= mask;
670 if (spec->gpio_led != oldval)
671 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
672 spec->gpio_led);
673}
674
675/* turn on/off mute LED via GPIO per vmaster hook */
676static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled)
677{
678 struct hda_codec *codec = private_data;
679 struct conexant_spec *spec = codec->spec;
680
681 cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
682}
683
684/* turn on/off mic-mute LED via GPIO per capture hook */
685static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
686 struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
688{
689 struct conexant_spec *spec = codec->spec;
690
691 if (ucontrol)
692 cxt_update_gpio_led(codec, spec->gpio_mic_led_mask,
693 ucontrol->value.integer.value[0] ||
694 ucontrol->value.integer.value[1]);
695}
696
697
698static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
699 const struct hda_fixup *fix, int action)
700{
701 struct conexant_spec *spec = codec->spec;
702 static const struct hda_verb gpio_init[] = {
703 { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 },
704 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
705 {}
706 };
707 codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led);
708
709 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
710 spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook;
711 spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook;
712 spec->gpio_led = 0;
713 spec->mute_led_polarity = 0;
714 spec->gpio_mute_led_mask = 0x01;
715 spec->gpio_mic_led_mask = 0x02;
716 }
717 snd_hda_add_verbs(codec, gpio_init);
718 if (spec->gpio_led)
719 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
720 spec->gpio_led);
721}
722
723
649/* ThinkPad X200 & co with cxt5051 */ 724/* ThinkPad X200 & co with cxt5051 */
650static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 725static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
651 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 726 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -799,6 +874,10 @@ static const struct hda_fixup cxt_fixups[] = {
799 .type = HDA_FIXUP_FUNC, 874 .type = HDA_FIXUP_FUNC,
800 .v.func = cxt_fixup_hp_gate_mic_jack, 875 .v.func = cxt_fixup_hp_gate_mic_jack,
801 }, 876 },
877 [CXT_FIXUP_MUTE_LED_GPIO] = {
878 .type = HDA_FIXUP_FUNC,
879 .v.func = cxt_fixup_mute_led_gpio,
880 },
802}; 881};
803 882
804static const struct snd_pci_quirk cxt5045_fixups[] = { 883static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -851,6 +930,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
851 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), 930 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), 931 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), 932 SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
933 SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
854 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 934 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
855 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 935 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
856 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 936 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
@@ -882,6 +962,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
882 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, 962 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" },
883 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, 963 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
884 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, 964 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" },
965 { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
885 {} 966 {}
886}; 967};
887 968
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1461ef8eb749..90e4ff87445e 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -177,6 +177,7 @@ struct hdmi_spec {
177 bool i915_bound; /* was i915 bound in this driver? */ 177 bool i915_bound; /* was i915 bound in this driver? */
178 178
179 struct hdac_chmap chmap; 179 struct hdac_chmap chmap;
180 hda_nid_t vendor_nid;
180}; 181};
181 182
182#ifdef CONFIG_SND_HDA_I915 183#ifdef CONFIG_SND_HDA_I915
@@ -383,7 +384,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
383 return 0; 384 return 0;
384} 385}
385 386
386static struct snd_kcontrol_new eld_bytes_ctl = { 387static const struct snd_kcontrol_new eld_bytes_ctl = {
387 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 388 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
388 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 389 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
389 .name = "ELD", 390 .name = "ELD",
@@ -2372,6 +2373,7 @@ static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
2372} 2373}
2373 2374
2374#define INTEL_VENDOR_NID 0x08 2375#define INTEL_VENDOR_NID 0x08
2376#define INTEL_GLK_VENDOR_NID 0x0B
2375#define INTEL_GET_VENDOR_VERB 0xf81 2377#define INTEL_GET_VENDOR_VERB 0xf81
2376#define INTEL_SET_VENDOR_VERB 0x781 2378#define INTEL_SET_VENDOR_VERB 0x781
2377#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ 2379#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
@@ -2381,14 +2383,15 @@ static void intel_haswell_enable_all_pins(struct hda_codec *codec,
2381 bool update_tree) 2383 bool update_tree)
2382{ 2384{
2383 unsigned int vendor_param; 2385 unsigned int vendor_param;
2386 struct hdmi_spec *spec = codec->spec;
2384 2387
2385 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2388 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2386 INTEL_GET_VENDOR_VERB, 0); 2389 INTEL_GET_VENDOR_VERB, 0);
2387 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) 2390 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
2388 return; 2391 return;
2389 2392
2390 vendor_param |= INTEL_EN_ALL_PIN_CVTS; 2393 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
2391 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2394 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2392 INTEL_SET_VENDOR_VERB, vendor_param); 2395 INTEL_SET_VENDOR_VERB, vendor_param);
2393 if (vendor_param == -1) 2396 if (vendor_param == -1)
2394 return; 2397 return;
@@ -2400,8 +2403,9 @@ static void intel_haswell_enable_all_pins(struct hda_codec *codec,
2400static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec) 2403static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2401{ 2404{
2402 unsigned int vendor_param; 2405 unsigned int vendor_param;
2406 struct hdmi_spec *spec = codec->spec;
2403 2407
2404 vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2408 vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0,
2405 INTEL_GET_VENDOR_VERB, 0); 2409 INTEL_GET_VENDOR_VERB, 0);
2406 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) 2410 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
2407 return; 2411 return;
@@ -2409,7 +2413,7 @@ static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2409 /* enable DP1.2 mode */ 2413 /* enable DP1.2 mode */
2410 vendor_param |= INTEL_EN_DP12; 2414 vendor_param |= INTEL_EN_DP12;
2411 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB); 2415 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB);
2412 snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0, 2416 snd_hda_codec_write_cache(codec, spec->vendor_nid, 0,
2413 INTEL_SET_VENDOR_VERB, vendor_param); 2417 INTEL_SET_VENDOR_VERB, vendor_param);
2414} 2418}
2415 2419
@@ -2503,7 +2507,7 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
2503} 2507}
2504 2508
2505/* Intel Haswell and onwards; audio component with eld notifier */ 2509/* Intel Haswell and onwards; audio component with eld notifier */
2506static int patch_i915_hsw_hdmi(struct hda_codec *codec) 2510static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid)
2507{ 2511{
2508 struct hdmi_spec *spec; 2512 struct hdmi_spec *spec;
2509 int err; 2513 int err;
@@ -2520,6 +2524,7 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2520 spec = codec->spec; 2524 spec = codec->spec;
2521 codec->dp_mst = true; 2525 codec->dp_mst = true;
2522 spec->dyn_pcm_assign = true; 2526 spec->dyn_pcm_assign = true;
2527 spec->vendor_nid = vendor_nid;
2523 2528
2524 intel_haswell_enable_all_pins(codec, true); 2529 intel_haswell_enable_all_pins(codec, true);
2525 intel_haswell_fixup_enable_dp12(codec); 2530 intel_haswell_fixup_enable_dp12(codec);
@@ -2548,6 +2553,16 @@ static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2548 return 0; 2553 return 0;
2549} 2554}
2550 2555
2556static int patch_i915_hsw_hdmi(struct hda_codec *codec)
2557{
2558 return intel_hsw_common_init(codec, INTEL_VENDOR_NID);
2559}
2560
2561static int patch_i915_glk_hdmi(struct hda_codec *codec)
2562{
2563 return intel_hsw_common_init(codec, INTEL_GLK_VENDOR_NID);
2564}
2565
2551/* Intel Baytrail and Braswell; with eld notifier */ 2566/* Intel Baytrail and Braswell; with eld notifier */
2552static int patch_i915_byt_hdmi(struct hda_codec *codec) 2567static int patch_i915_byt_hdmi(struct hda_codec *codec)
2553{ 2568{
@@ -3800,7 +3815,7 @@ HDA_CODEC_ENTRY(0x80862808, "Broadwell HDMI", patch_i915_hsw_hdmi),
3800HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), 3815HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi),
3801HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), 3816HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi),
3802HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), 3817HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi),
3803HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_hsw_hdmi), 3818HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
3804HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), 3819HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
3805HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), 3820HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
3806HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi), 3821HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 299835d1fbaa..58df440013c5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1800,6 +1800,7 @@ enum {
1800 ALC882_FIXUP_NO_PRIMARY_HP, 1800 ALC882_FIXUP_NO_PRIMARY_HP,
1801 ALC887_FIXUP_ASUS_BASS, 1801 ALC887_FIXUP_ASUS_BASS,
1802 ALC887_FIXUP_BASS_CHMAP, 1802 ALC887_FIXUP_BASS_CHMAP,
1803 ALC1220_FIXUP_GB_DUAL_CODECS,
1803}; 1804};
1804 1805
1805static void alc889_fixup_coef(struct hda_codec *codec, 1806static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1962static void alc_fixup_bass_chmap(struct hda_codec *codec, 1963static void alc_fixup_bass_chmap(struct hda_codec *codec,
1963 const struct hda_fixup *fix, int action); 1964 const struct hda_fixup *fix, int action);
1964 1965
1966/* For dual-codec configuration, we need to disable some features to avoid
1967 * conflicts of kctls and PCM streams
1968 */
1969static void alc_fixup_dual_codecs(struct hda_codec *codec,
1970 const struct hda_fixup *fix, int action)
1971{
1972 struct alc_spec *spec = codec->spec;
1973
1974 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1975 return;
1976 /* disable vmaster */
1977 spec->gen.suppress_vmaster = 1;
1978 /* auto-mute and auto-mic switch don't work with multiple codecs */
1979 spec->gen.suppress_auto_mute = 1;
1980 spec->gen.suppress_auto_mic = 1;
1981 /* disable aamix as well */
1982 spec->gen.mixer_nid = 0;
1983 /* add location prefix to avoid conflicts */
1984 codec->force_pin_prefix = 1;
1985}
1986
1987static void rename_ctl(struct hda_codec *codec, const char *oldname,
1988 const char *newname)
1989{
1990 struct snd_kcontrol *kctl;
1991
1992 kctl = snd_hda_find_mixer_ctl(codec, oldname);
1993 if (kctl)
1994 strcpy(kctl->id.name, newname);
1995}
1996
1997static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
1998 const struct hda_fixup *fix,
1999 int action)
2000{
2001 alc_fixup_dual_codecs(codec, fix, action);
2002 switch (action) {
2003 case HDA_FIXUP_ACT_PRE_PROBE:
2004 /* override card longname to provide a unique UCM profile */
2005 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2006 break;
2007 case HDA_FIXUP_ACT_BUILD:
2008 /* rename Capture controls depending on the codec */
2009 rename_ctl(codec, "Capture Volume",
2010 codec->addr == 0 ?
2011 "Rear-Panel Capture Volume" :
2012 "Front-Panel Capture Volume");
2013 rename_ctl(codec, "Capture Switch",
2014 codec->addr == 0 ?
2015 "Rear-Panel Capture Switch" :
2016 "Front-Panel Capture Switch");
2017 break;
2018 }
2019}
2020
1965static const struct hda_fixup alc882_fixups[] = { 2021static const struct hda_fixup alc882_fixups[] = {
1966 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 2022 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1967 .type = HDA_FIXUP_PINS, 2023 .type = HDA_FIXUP_PINS,
@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
2198 .type = HDA_FIXUP_FUNC, 2254 .type = HDA_FIXUP_FUNC,
2199 .v.func = alc_fixup_bass_chmap, 2255 .v.func = alc_fixup_bass_chmap,
2200 }, 2256 },
2257 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2258 .type = HDA_FIXUP_FUNC,
2259 .v.func = alc1220_fixup_gb_dual_codecs,
2260 },
2201}; 2261};
2202 2262
2203static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2263static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2267 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2327 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2268 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2328 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), 2329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2330 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2270 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2331 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2271 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2332 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2272 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2333 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -4663,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4663 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4724 { 0x1b, 0x21114000 }, /* dock speaker pin */
4664 {} 4725 {}
4665 }; 4726 };
4666 struct snd_kcontrol *kctl;
4667 4727
4668 switch (action) { 4728 switch (action) {
4669 case HDA_FIXUP_ACT_PRE_PROBE: 4729 case HDA_FIXUP_ACT_PRE_PROBE:
@@ -4678,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4678 /* this is a bit tricky; give more sane names for the main 4738 /* this is a bit tricky; give more sane names for the main
4679 * (tablet) speaker and the dock speaker, respectively 4739 * (tablet) speaker and the dock speaker, respectively
4680 */ 4740 */
4681 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); 4741 rename_ctl(codec, "Speaker Playback Switch",
4682 if (kctl) 4742 "Dock Speaker Playback Switch");
4683 strcpy(kctl->id.name, "Dock Speaker Playback Switch"); 4743 rename_ctl(codec, "Bass Speaker Playback Switch",
4684 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); 4744 "Speaker Playback Switch");
4685 if (kctl)
4686 strcpy(kctl->id.name, "Speaker Playback Switch");
4687 break; 4745 break;
4688 } 4746 }
4689} 4747}
@@ -4766,6 +4824,30 @@ static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4766 } 4824 }
4767} 4825}
4768 4826
4827static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
4828 const struct hda_fixup *fix,
4829 int action)
4830{
4831 alc_fixup_dual_codecs(codec, fix, action);
4832 switch (action) {
4833 case HDA_FIXUP_ACT_PRE_PROBE:
4834 /* override card longname to provide a unique UCM profile */
4835 strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
4836 break;
4837 case HDA_FIXUP_ACT_BUILD:
4838 /* rename Capture controls depending on the codec */
4839 rename_ctl(codec, "Capture Volume",
4840 codec->addr == 0 ?
4841 "Rear-Panel Capture Volume" :
4842 "Front-Panel Capture Volume");
4843 rename_ctl(codec, "Capture Switch",
4844 codec->addr == 0 ?
4845 "Rear-Panel Capture Switch" :
4846 "Front-Panel Capture Switch");
4847 break;
4848 }
4849}
4850
4769/* for hda_fixup_thinkpad_acpi() */ 4851/* for hda_fixup_thinkpad_acpi() */
4770#include "thinkpad_helper.c" 4852#include "thinkpad_helper.c"
4771 4853
@@ -4833,6 +4915,8 @@ enum {
4833 ALC290_FIXUP_SUBWOOFER_HSJACK, 4915 ALC290_FIXUP_SUBWOOFER_HSJACK,
4834 ALC269_FIXUP_THINKPAD_ACPI, 4916 ALC269_FIXUP_THINKPAD_ACPI,
4835 ALC269_FIXUP_DMIC_THINKPAD_ACPI, 4917 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
4918 ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
4919 ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
4836 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4920 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4837 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4921 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4838 ALC255_FIXUP_HEADSET_MODE, 4922 ALC255_FIXUP_HEADSET_MODE,
@@ -4872,6 +4956,12 @@ enum {
4872 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, 4956 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
4873 ALC269_FIXUP_ATIV_BOOK_8, 4957 ALC269_FIXUP_ATIV_BOOK_8,
4874 ALC221_FIXUP_HP_MIC_NO_PRESENCE, 4958 ALC221_FIXUP_HP_MIC_NO_PRESENCE,
4959 ALC256_FIXUP_ASUS_HEADSET_MODE,
4960 ALC256_FIXUP_ASUS_MIC,
4961 ALC256_FIXUP_ASUS_AIO_GPIO2,
4962 ALC233_FIXUP_ASUS_MIC_NO_PRESENCE,
4963 ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
4964 ALC233_FIXUP_LENOVO_MULTI_CODECS,
4875}; 4965};
4876 4966
4877static const struct hda_fixup alc269_fixups[] = { 4967static const struct hda_fixup alc269_fixups[] = {
@@ -5289,6 +5379,24 @@ static const struct hda_fixup alc269_fixups[] = {
5289 .chained = true, 5379 .chained = true,
5290 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5380 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5291 }, 5381 },
5382 [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = {
5383 .type = HDA_FIXUP_PINS,
5384 .v.pins = (const struct hda_pintbl[]) {
5385 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5386 { }
5387 },
5388 .chained = true,
5389 .chain_id = ALC255_FIXUP_HEADSET_MODE
5390 },
5391 [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5392 .type = HDA_FIXUP_PINS,
5393 .v.pins = (const struct hda_pintbl[]) {
5394 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5395 { }
5396 },
5397 .chained = true,
5398 .chain_id = ALC255_FIXUP_HEADSET_MODE
5399 },
5292 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5400 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5293 .type = HDA_FIXUP_PINS, 5401 .type = HDA_FIXUP_PINS,
5294 .v.pins = (const struct hda_pintbl[]) { 5402 .v.pins = (const struct hda_pintbl[]) {
@@ -5579,6 +5687,54 @@ static const struct hda_fixup alc269_fixups[] = {
5579 .chained = true, 5687 .chained = true,
5580 .chain_id = ALC269_FIXUP_HEADSET_MODE 5688 .chain_id = ALC269_FIXUP_HEADSET_MODE
5581 }, 5689 },
5690 [ALC256_FIXUP_ASUS_HEADSET_MODE] = {
5691 .type = HDA_FIXUP_FUNC,
5692 .v.func = alc_fixup_headset_mode,
5693 },
5694 [ALC256_FIXUP_ASUS_MIC] = {
5695 .type = HDA_FIXUP_PINS,
5696 .v.pins = (const struct hda_pintbl[]) {
5697 { 0x13, 0x90a60160 }, /* use as internal mic */
5698 { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */
5699 { }
5700 },
5701 .chained = true,
5702 .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
5703 },
5704 [ALC256_FIXUP_ASUS_AIO_GPIO2] = {
5705 .type = HDA_FIXUP_VERBS,
5706 .v.verbs = (const struct hda_verb[]) {
5707 /* Set up GPIO2 for the speaker amp */
5708 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
5709 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
5710 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
5711 {}
5712 },
5713 },
5714 [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = {
5715 .type = HDA_FIXUP_PINS,
5716 .v.pins = (const struct hda_pintbl[]) {
5717 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5718 { }
5719 },
5720 .chained = true,
5721 .chain_id = ALC269_FIXUP_HEADSET_MIC
5722 },
5723 [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = {
5724 .type = HDA_FIXUP_VERBS,
5725 .v.verbs = (const struct hda_verb[]) {
5726 /* Enables internal speaker */
5727 {0x20, AC_VERB_SET_COEF_INDEX, 0x40},
5728 {0x20, AC_VERB_SET_PROC_COEF, 0x8800},
5729 {}
5730 },
5731 .chained = true,
5732 .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE
5733 },
5734 [ALC233_FIXUP_LENOVO_MULTI_CODECS] = {
5735 .type = HDA_FIXUP_FUNC,
5736 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
5737 },
5582}; 5738};
5583 5739
5584static const struct snd_pci_quirk alc269_fixup_tbl[] = { 5740static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -5692,15 +5848,27 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5692 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 5848 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
5693 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5849 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), 5850 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
5851 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
5695 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 5852 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5696 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5853 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5854 SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
5697 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5855 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5856 SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
5857 SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
5858 SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
5698 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), 5859 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5699 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), 5860 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5700 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 5861 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5701 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 5862 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5702 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 5863 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5703 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5864 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5865 SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5866 SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5867 SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
5868 SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
5869 SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
5870 SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
5871 SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
5704 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 5872 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5705 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 5873 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5706 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), 5874 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
@@ -5721,6 +5889,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5721 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), 5889 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), 5890 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), 5891 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
5892 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
5724 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 5893 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5725 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 5894 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5726 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 5895 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
@@ -5875,6 +6044,18 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
5875 {0x21, 0x03211020} 6044 {0x21, 0x03211020}
5876 6045
5877static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 6046static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
6047 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
6048 {0x12, 0x90a601c0},
6049 {0x14, 0x90171120},
6050 {0x21, 0x02211030}),
6051 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6052 {0x14, 0x90170110},
6053 {0x1b, 0x90a70130},
6054 {0x21, 0x03211020}),
6055 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
6056 {0x1a, 0x90a70130},
6057 {0x1b, 0x90170110},
6058 {0x21, 0x03211020}),
5878 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 6059 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5879 ALC225_STANDARD_PINS, 6060 ALC225_STANDARD_PINS,
5880 {0x12, 0xb7a60130}, 6061 {0x12, 0xb7a60130},
@@ -5995,6 +6176,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5995 {0x21, 0x02211020}), 6176 {0x21, 0x02211020}),
5996 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 6177 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5997 ALC256_STANDARD_PINS), 6178 ALC256_STANDARD_PINS),
6179 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6180 {0x14, 0x90170110},
6181 {0x1b, 0x90a70130},
6182 {0x21, 0x04211020}),
6183 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC,
6184 {0x14, 0x90170110},
6185 {0x1b, 0x90a70130},
6186 {0x21, 0x03211020}),
5998 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 6187 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5999 {0x12, 0x90a60130}, 6188 {0x12, 0x90a60130},
6000 {0x14, 0x90170110}, 6189 {0x14, 0x90170110},
@@ -6714,6 +6903,7 @@ enum {
6714 ALC668_FIXUP_DELL_DISABLE_AAMIX, 6903 ALC668_FIXUP_DELL_DISABLE_AAMIX,
6715 ALC668_FIXUP_DELL_XPS13, 6904 ALC668_FIXUP_DELL_XPS13,
6716 ALC662_FIXUP_ASUS_Nx50, 6905 ALC662_FIXUP_ASUS_Nx50,
6906 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
6717 ALC668_FIXUP_ASUS_Nx51, 6907 ALC668_FIXUP_ASUS_Nx51,
6718 ALC891_FIXUP_HEADSET_MODE, 6908 ALC891_FIXUP_HEADSET_MODE,
6719 ALC891_FIXUP_DELL_MIC_NO_PRESENCE, 6909 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
@@ -6721,6 +6911,7 @@ enum {
6721 ALC892_FIXUP_ASROCK_MOBO, 6911 ALC892_FIXUP_ASROCK_MOBO,
6722 ALC662_FIXUP_USI_FUNC, 6912 ALC662_FIXUP_USI_FUNC,
6723 ALC662_FIXUP_USI_HEADSET_MODE, 6913 ALC662_FIXUP_USI_HEADSET_MODE,
6914 ALC662_FIXUP_LENOVO_MULTI_CODECS,
6724}; 6915};
6725 6916
6726static const struct hda_fixup alc662_fixups[] = { 6917static const struct hda_fixup alc662_fixups[] = {
@@ -6967,14 +7158,21 @@ static const struct hda_fixup alc662_fixups[] = {
6967 .chained = true, 7158 .chained = true,
6968 .chain_id = ALC662_FIXUP_BASS_1A 7159 .chain_id = ALC662_FIXUP_BASS_1A
6969 }, 7160 },
7161 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7162 .type = HDA_FIXUP_FUNC,
7163 .v.func = alc_fixup_headset_mode_alc668,
7164 .chain_id = ALC662_FIXUP_BASS_CHMAP
7165 },
6970 [ALC668_FIXUP_ASUS_Nx51] = { 7166 [ALC668_FIXUP_ASUS_Nx51] = {
6971 .type = HDA_FIXUP_PINS, 7167 .type = HDA_FIXUP_PINS,
6972 .v.pins = (const struct hda_pintbl[]) { 7168 .v.pins = (const struct hda_pintbl[]) {
6973 {0x1a, 0x90170151}, /* bass speaker */ 7169 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7170 { 0x1a, 0x90170151 }, /* bass speaker */
7171 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6974 {} 7172 {}
6975 }, 7173 },
6976 .chained = true, 7174 .chained = true,
6977 .chain_id = ALC662_FIXUP_BASS_CHMAP, 7175 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
6978 }, 7176 },
6979 [ALC891_FIXUP_HEADSET_MODE] = { 7177 [ALC891_FIXUP_HEADSET_MODE] = {
6980 .type = HDA_FIXUP_FUNC, 7178 .type = HDA_FIXUP_FUNC,
@@ -7019,6 +7217,10 @@ static const struct hda_fixup alc662_fixups[] = {
7019 .chained = true, 7217 .chained = true,
7020 .chain_id = ALC662_FIXUP_USI_FUNC 7218 .chain_id = ALC662_FIXUP_USI_FUNC
7021 }, 7219 },
7220 [ALC662_FIXUP_LENOVO_MULTI_CODECS] = {
7221 .type = HDA_FIXUP_FUNC,
7222 .v.func = alc233_alc662_fixup_lenovo_dual_codecs,
7223 },
7022}; 7224};
7023 7225
7024static const struct snd_pci_quirk alc662_fixup_tbl[] = { 7226static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -7056,6 +7258,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
7056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 7258 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
7057 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 7259 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
7058 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 7260 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
7261 SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
7059 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 7262 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
7060 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 7263 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
7061 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), 7264 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 3bfdc78cbc5f..da5f37b7fdd0 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -432,7 +432,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
432 return 0; 432 return 0;
433} 433}
434 434
435static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = 435static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =
436{ 436{
437 .access = (SNDRV_CTL_ELEM_ACCESS_READ), 437 .access = (SNDRV_CTL_ELEM_ACCESS_READ),
438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 5cb587cf360e..ec07136fc288 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -719,7 +719,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
719 return ndata != data; 719 return ndata != data;
720} 720}
721 721
722static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = { 722static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {
723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
724 .name = "Input Sensitivity Switch", 724 .name = "Input Sensitivity Switch",
725 .info = snd_ice1712_ewx_io_sense_info, 725 .info = snd_ice1712_ewx_io_sense_info,
@@ -728,7 +728,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {
728 .count = 8, 728 .count = 8,
729}; 729};
730 730
731static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = { 731static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = {
732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
733 .name = "Output Sensitivity Switch", 733 .name = "Output Sensitivity Switch",
734 .info = snd_ice1712_ewx_io_sense_info, 734 .info = snd_ice1712_ewx_io_sense_info,
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index b4aa4c1370a8..1d8612cabb9e 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -279,7 +279,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
279 return val != nval; 279 return val != nval;
280} 280}
281 281
282static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = { 282static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = {
283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
284 .name = "Digital Mixer To AC97", 284 .name = "Digital Mixer To AC97",
285 .info = snd_ice1712_digmix_route_ac97_info, 285 .info = snd_ice1712_digmix_route_ac97_info,
@@ -1410,7 +1410,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = {
1410 .private_value = 10, 1410 .private_value = 10,
1411}; 1411};
1412 1412
1413static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = { 1413static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = {
1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), 1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
1416 .info = snd_ice1712_pro_mixer_switch_info, 1416 .info = snd_ice1712_pro_mixer_switch_info,
@@ -1432,7 +1432,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = {
1432 .tlv = { .p = db_scale_playback } 1432 .tlv = { .p = db_scale_playback }
1433}; 1433};
1434 1434
1435static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = { 1435static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = {
1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), 1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
1438 .info = snd_ice1712_pro_mixer_volume_info, 1438 .info = snd_ice1712_pro_mixer_volume_info,
@@ -1630,7 +1630,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
1630 return 0; 1630 return 0;
1631} 1631}
1632 1632
1633static struct snd_kcontrol_new snd_ice1712_eeprom = { 1633static const struct snd_kcontrol_new snd_ice1712_eeprom = {
1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1635 .name = "ICE1712 EEPROM", 1635 .name = "ICE1712 EEPROM",
1636 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1636 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1666,7 +1666,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
1666 return 0; 1666 return 0;
1667} 1667}
1668 1668
1669static struct snd_kcontrol_new snd_ice1712_spdif_default = 1669static const struct snd_kcontrol_new snd_ice1712_spdif_default =
1670{ 1670{
1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1717,7 +1717,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1717 return 0; 1717 return 0;
1718} 1718}
1719 1719
1720static struct snd_kcontrol_new snd_ice1712_spdif_maskc = 1720static const struct snd_kcontrol_new snd_ice1712_spdif_maskc =
1721{ 1721{
1722 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1722 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1726,7 +1726,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc =
1726 .get = snd_ice1712_spdif_maskc_get, 1726 .get = snd_ice1712_spdif_maskc_get,
1727}; 1727};
1728 1728
1729static struct snd_kcontrol_new snd_ice1712_spdif_maskp = 1729static const struct snd_kcontrol_new snd_ice1712_spdif_maskp =
1730{ 1730{
1731 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1731 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1753,7 +1753,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
1753 return 0; 1753 return 0;
1754} 1754}
1755 1755
1756static struct snd_kcontrol_new snd_ice1712_spdif_stream = 1756static const struct snd_kcontrol_new snd_ice1712_spdif_stream =
1757{ 1757{
1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE), 1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1878,7 +1878,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1878 return change; 1878 return change;
1879} 1879}
1880 1880
1881static struct snd_kcontrol_new snd_ice1712_pro_internal_clock = { 1881static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock = {
1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1883 .name = "Multi Track Internal Clock", 1883 .name = "Multi Track Internal Clock",
1884 .info = snd_ice1712_pro_internal_clock_info, 1884 .info = snd_ice1712_pro_internal_clock_info,
@@ -1943,7 +1943,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont
1943 return change; 1943 return change;
1944} 1944}
1945 1945
1946static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = { 1946static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = {
1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1948 .name = "Multi Track Internal Clock Default", 1948 .name = "Multi Track Internal Clock Default",
1949 .info = snd_ice1712_pro_internal_clock_default_info, 1949 .info = snd_ice1712_pro_internal_clock_default_info,
@@ -1974,7 +1974,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
1974 return change; 1974 return change;
1975} 1975}
1976 1976
1977static struct snd_kcontrol_new snd_ice1712_pro_rate_locking = { 1977static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking = {
1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1979 .name = "Multi Track Rate Locking", 1979 .name = "Multi Track Rate Locking",
1980 .info = snd_ice1712_pro_rate_locking_info, 1980 .info = snd_ice1712_pro_rate_locking_info,
@@ -2005,7 +2005,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
2005 return change; 2005 return change;
2006} 2006}
2007 2007
2008static struct snd_kcontrol_new snd_ice1712_pro_rate_reset = { 2008static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset = {
2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2010 .name = "Multi Track Rate Reset", 2010 .name = "Multi Track Rate Reset",
2011 .info = snd_ice1712_pro_rate_reset_info, 2011 .info = snd_ice1712_pro_rate_reset_info,
@@ -2173,7 +2173,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = {
2173 .put = snd_ice1712_pro_route_analog_put, 2173 .put = snd_ice1712_pro_route_analog_put,
2174}; 2174};
2175 2175
2176static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = { 2176static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = {
2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2179 .info = snd_ice1712_pro_route_info, 2179 .info = snd_ice1712_pro_route_info,
@@ -2215,7 +2215,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
2215 return change; 2215 return change;
2216} 2216}
2217 2217
2218static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = { 2218static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = {
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2220 .name = "Multi Track Volume Rate", 2220 .name = "Multi Track Volume Rate",
2221 .info = snd_ice1712_pro_volume_rate_info, 2221 .info = snd_ice1712_pro_volume_rate_info,
@@ -2248,7 +2248,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
2248 return 0; 2248 return 0;
2249} 2249}
2250 2250
2251static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = { 2251static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = {
2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2253 .name = "Multi Track Peak", 2253 .name = "Multi Track Peak",
2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 842744e7a139..9cd6e55c0642 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1598,7 +1598,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
1598 return 0; 1598 return 0;
1599} 1599}
1600 1600
1601static struct snd_kcontrol_new snd_vt1724_eeprom = { 1601static const struct snd_kcontrol_new snd_vt1724_eeprom = {
1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1603 .name = "ICE1724 EEPROM", 1603 .name = "ICE1724 EEPROM",
1604 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1604 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1711,7 +1711,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
1711 return val != old; 1711 return val != old;
1712} 1712}
1713 1713
1714static struct snd_kcontrol_new snd_vt1724_spdif_default = 1714static const struct snd_kcontrol_new snd_vt1724_spdif_default =
1715{ 1715{
1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), 1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1743,7 +1743,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1743 return 0; 1743 return 0;
1744} 1744}
1745 1745
1746static struct snd_kcontrol_new snd_vt1724_spdif_maskc = 1746static const struct snd_kcontrol_new snd_vt1724_spdif_maskc =
1747{ 1747{
1748 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1748 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1752,7 +1752,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc =
1752 .get = snd_vt1724_spdif_maskc_get, 1752 .get = snd_vt1724_spdif_maskc_get,
1753}; 1753};
1754 1754
1755static struct snd_kcontrol_new snd_vt1724_spdif_maskp = 1755static const struct snd_kcontrol_new snd_vt1724_spdif_maskp =
1756{ 1756{
1757 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1789,7 +1789,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
1789 return old != val; 1789 return old != val;
1790} 1790}
1791 1791
1792static struct snd_kcontrol_new snd_vt1724_spdif_switch = 1792static const struct snd_kcontrol_new snd_vt1724_spdif_switch =
1793{ 1793{
1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1795 /* FIXME: the following conflict with IEC958 Playback Route */ 1795 /* FIXME: the following conflict with IEC958 Playback Route */
@@ -1964,7 +1964,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1964 return old_rate != new_rate; 1964 return old_rate != new_rate;
1965} 1965}
1966 1966
1967static struct snd_kcontrol_new snd_vt1724_pro_internal_clock = { 1967static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock = {
1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1969 .name = "Multi Track Internal Clock", 1969 .name = "Multi Track Internal Clock",
1970 .info = snd_vt1724_pro_internal_clock_info, 1970 .info = snd_vt1724_pro_internal_clock_info,
@@ -1995,7 +1995,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
1995 return change; 1995 return change;
1996} 1996}
1997 1997
1998static struct snd_kcontrol_new snd_vt1724_pro_rate_locking = { 1998static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking = {
1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2000 .name = "Multi Track Rate Locking", 2000 .name = "Multi Track Rate Locking",
2001 .info = snd_vt1724_pro_rate_locking_info, 2001 .info = snd_vt1724_pro_rate_locking_info,
@@ -2026,7 +2026,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
2026 return change; 2026 return change;
2027} 2027}
2028 2028
2029static struct snd_kcontrol_new snd_vt1724_pro_rate_reset = { 2029static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset = {
2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2031 .name = "Multi Track Rate Reset", 2031 .name = "Multi Track Rate Reset",
2032 .info = snd_vt1724_pro_rate_reset_info, 2032 .info = snd_vt1724_pro_rate_reset_info,
@@ -2151,7 +2151,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route =
2151 .put = snd_vt1724_pro_route_analog_put, 2151 .put = snd_vt1724_pro_route_analog_put,
2152}; 2152};
2153 2153
2154static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = { 2154static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = {
2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
2157 .info = snd_vt1724_pro_route_info, 2157 .info = snd_vt1724_pro_route_info,
@@ -2187,7 +2187,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
2187 return 0; 2187 return 0;
2188} 2188}
2189 2189
2190static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = { 2190static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = {
2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2192 .name = "Multi Track Peak", 2192 .name = "Multi Track Peak",
2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index e7fe15dd5a90..cb25acf7bc49 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -645,7 +645,7 @@ static int lola_input_src_put(struct snd_kcontrol *kcontrol,
645 return lola_set_src_config(chip, mask, true); 645 return lola_set_src_config(chip, mask, true);
646} 646}
647 647
648static struct snd_kcontrol_new lola_input_src_mixer = { 648static const struct snd_kcontrol_new lola_input_src_mixer = {
649 .name = "Digital SRC Capture Switch", 649 .name = "Digital SRC Capture Switch",
650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
651 .info = lola_input_src_info, 651 .info = lola_input_src_info,
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index c0f0c349c3ec..f9c3e86d55d5 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -899,7 +899,7 @@ static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
899 return changed; 899 return changed;
900} 900}
901 901
902static struct snd_kcontrol_new lx_control_playback_switch = { 902static const struct snd_kcontrol_new lx_control_playback_switch = {
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "PCM Playback Switch", 904 .name = "PCM Playback Switch",
905 .index = 0, 905 .index = 0,
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 51e53497f0ad..4a4616aac787 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -448,7 +448,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
448 return changed; 448 return changed;
449} 449}
450 450
451static struct snd_kcontrol_new mixart_control_output_switch = { 451static const struct snd_kcontrol_new mixart_control_output_switch = {
452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
453 .name = "Master Playback Switch", 453 .name = "Master Playback Switch",
454 .info = mixart_sw_info, /* shared */ 454 .info = mixart_sw_info, /* shared */
@@ -1024,7 +1024,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1024 return changed; 1024 return changed;
1025} 1025}
1026 1026
1027static struct snd_kcontrol_new mixart_control_monitor_vol = { 1027static const struct snd_kcontrol_new mixart_control_monitor_vol = {
1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1091,7 +1091,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1091 return (changed != 0); 1091 return (changed != 0);
1092} 1092}
1093 1093
1094static struct snd_kcontrol_new mixart_control_monitor_sw = { 1094static const struct snd_kcontrol_new mixart_control_monitor_sw = {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Monitoring Switch", 1096 .name = "Monitoring Switch",
1097 .info = mixart_sw_info, /* shared */ 1097 .info = mixart_sw_info, /* shared */
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 74afb6b75976..e36ed8af55ad 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -767,6 +767,8 @@ static int get_oxygen_model(struct oxygen *chip,
767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia", 767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
768 [MODEL_SERENADE] = "TempoTec HiFier Serenade", 768 [MODEL_SERENADE] = "TempoTec HiFier Serenade",
769 [MODEL_HG2PCI] = "CMI8787-HG2PCI", 769 [MODEL_HG2PCI] = "CMI8787-HG2PCI",
770 [MODEL_XONAR_DG] = "Xonar DG",
771 [MODEL_XONAR_DGX] = "Xonar DGX",
770 }; 772 };
771 773
772 chip->model = model_generic; 774 chip->model = model_generic;
@@ -829,12 +831,8 @@ static int get_oxygen_model(struct oxygen *chip,
829 chip->model.dac_channels_mixer = 2; 831 chip->model.dac_channels_mixer = 2;
830 break; 832 break;
831 case MODEL_XONAR_DG: 833 case MODEL_XONAR_DG:
832 chip->model = model_xonar_dg;
833 chip->model.shortname = "Xonar DG";
834 break;
835 case MODEL_XONAR_DGX: 834 case MODEL_XONAR_DGX:
836 chip->model = model_xonar_dg; 835 chip->model = model_xonar_dg;
837 chip->model.shortname = "Xonar DGX";
838 break; 836 break;
839 } 837 }
840 if (id->driver_data == MODEL_MERIDIAN || 838 if (id->driver_data == MODEL_MERIDIAN ||
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
index 6a56e5306a65..8b4d0282efb8 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.c
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -744,7 +744,7 @@ static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
744 return changed; 744 return changed;
745} 745}
746 746
747static struct snd_kcontrol_new hr222_control_mic_level = { 747static const struct snd_kcontrol_new hr222_control_mic_level = {
748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
750 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 750 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -794,7 +794,7 @@ static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
794 return changed; 794 return changed;
795} 795}
796 796
797static struct snd_kcontrol_new hr222_control_mic_boost = { 797static const struct snd_kcontrol_new hr222_control_mic_boost = {
798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
800 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 800 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -836,7 +836,7 @@ static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
836 return changed; 836 return changed;
837} 837}
838 838
839static struct snd_kcontrol_new hr222_phantom_power_switch = { 839static const struct snd_kcontrol_new hr222_phantom_power_switch = {
840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
841 .name = "Phantom Power Switch", 841 .name = "Phantom Power Switch",
842 .info = hr222_phantom_power_info, 842 .info = hr222_phantom_power_info,
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index 63136c4f3f3d..36875df30dbf 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -235,7 +235,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
235 return changed; 235 return changed;
236} 236}
237 237
238static struct snd_kcontrol_new pcxhr_control_output_switch = { 238static const struct snd_kcontrol_new pcxhr_control_output_switch = {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch", 240 .name = "Master Playback Switch",
241 .info = pcxhr_sw_info, /* shared */ 241 .info = pcxhr_sw_info, /* shared */
@@ -460,7 +460,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
460 return changed; 460 return changed;
461} 461}
462 462
463static struct snd_kcontrol_new pcxhr_control_pcm_switch = { 463static const struct snd_kcontrol_new pcxhr_control_pcm_switch = {
464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
465 .name = "PCM Playback Switch", 465 .name = "PCM Playback Switch",
466 .count = PCXHR_PLAYBACK_STREAMS, 466 .count = PCXHR_PLAYBACK_STREAMS,
@@ -509,7 +509,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
509 return changed; 509 return changed;
510} 510}
511 511
512static struct snd_kcontrol_new pcxhr_control_monitor_vol = { 512static const struct snd_kcontrol_new pcxhr_control_monitor_vol = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
515 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 515 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -562,7 +562,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
562 return (changed != 0); 562 return (changed != 0);
563} 563}
564 564
565static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 565static const struct snd_kcontrol_new pcxhr_control_monitor_sw = {
566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
567 .name = "Monitoring Playback Switch", 567 .name = "Monitoring Playback Switch",
568 .info = pcxhr_sw_info, /* shared */ 568 .info = pcxhr_sw_info, /* shared */
@@ -697,7 +697,7 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
697 return ret; 697 return ret;
698} 698}
699 699
700static struct snd_kcontrol_new pcxhr_control_audio_src = { 700static const struct snd_kcontrol_new pcxhr_control_audio_src = {
701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
702 .name = "Capture Source", 702 .name = "Capture Source",
703 .info = pcxhr_audio_src_info, 703 .info = pcxhr_audio_src_info,
@@ -798,7 +798,7 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
798 return ret; 798 return ret;
799} 799}
800 800
801static struct snd_kcontrol_new pcxhr_control_clock_type = { 801static const struct snd_kcontrol_new pcxhr_control_clock_type = {
802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
803 .name = "Clock Mode", 803 .name = "Clock Mode",
804 .info = pcxhr_clock_type_info, 804 .info = pcxhr_clock_type_info,
@@ -842,7 +842,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
842 return 0; 842 return 0;
843} 843}
844 844
845static struct snd_kcontrol_new pcxhr_control_clock_rate = { 845static const struct snd_kcontrol_new pcxhr_control_clock_rate = {
846 .access = SNDRV_CTL_ELEM_ACCESS_READ, 846 .access = SNDRV_CTL_ELEM_ACCESS_READ,
847 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 847 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
848 .name = "Clock Rates", 848 .name = "Clock Rates",
@@ -1017,14 +1017,14 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
1017 return changed; 1017 return changed;
1018} 1018}
1019 1019
1020static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = { 1020static const struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
1021 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1021 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1024 .info = pcxhr_iec958_info, 1024 .info = pcxhr_iec958_info,
1025 .get = pcxhr_iec958_mask_get 1025 .get = pcxhr_iec958_mask_get
1026}; 1026};
1027static struct snd_kcontrol_new pcxhr_control_playback_iec958 = { 1027static const struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1030 .info = pcxhr_iec958_info, 1030 .info = pcxhr_iec958_info,
@@ -1033,14 +1033,14 @@ static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
1033 .private_value = 0 /* playback */ 1033 .private_value = 0 /* playback */
1034}; 1034};
1035 1035
1036static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = { 1036static const struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
1037 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1037 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1040 .info = pcxhr_iec958_info, 1040 .info = pcxhr_iec958_info,
1041 .get = pcxhr_iec958_mask_get 1041 .get = pcxhr_iec958_mask_get
1042}; 1042};
1043static struct snd_kcontrol_new pcxhr_control_capture_iec958 = { 1043static const struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
1044 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1044 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 92ad2d7a6bf8..64d3b8eba4bb 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2356,7 +2356,7 @@ static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
2356 return change; 2356 return change;
2357} 2357}
2358 2358
2359static struct snd_kcontrol_new snd_trident_spdif_control = 2359static const struct snd_kcontrol_new snd_trident_spdif_control =
2360{ 2360{
2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
@@ -2419,7 +2419,7 @@ static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
2419 return change; 2419 return change;
2420} 2420}
2421 2421
2422static struct snd_kcontrol_new snd_trident_spdif_default = 2422static const struct snd_kcontrol_new snd_trident_spdif_default =
2423{ 2423{
2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2452,7 +2452,7 @@ static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
2452 return 0; 2452 return 0;
2453} 2453}
2454 2454
2455static struct snd_kcontrol_new snd_trident_spdif_mask = 2455static const struct snd_kcontrol_new snd_trident_spdif_mask =
2456{ 2456{
2457 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2457 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2514,7 +2514,7 @@ static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
2514 return change; 2514 return change;
2515} 2515}
2516 2516
2517static struct snd_kcontrol_new snd_trident_spdif_stream = 2517static const struct snd_kcontrol_new snd_trident_spdif_stream =
2518{ 2518{
2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2564,7 +2564,7 @@ static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
2564 return change; 2564 return change;
2565} 2565}
2566 2566
2567static struct snd_kcontrol_new snd_trident_ac97_rear_control = 2567static const struct snd_kcontrol_new snd_trident_ac97_rear_control =
2568{ 2568{
2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2570 .name = "Rear Path", 2570 .name = "Rear Path",
@@ -2622,7 +2622,7 @@ static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
2622 return change; 2622 return change;
2623} 2623}
2624 2624
2625static struct snd_kcontrol_new snd_trident_vol_music_control = 2625static const struct snd_kcontrol_new snd_trident_vol_music_control =
2626{ 2626{
2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2628 .name = "Music Playback Volume", 2628 .name = "Music Playback Volume",
@@ -2633,7 +2633,7 @@ static struct snd_kcontrol_new snd_trident_vol_music_control =
2633 .tlv = { .p = db_scale_gvol }, 2633 .tlv = { .p = db_scale_gvol },
2634}; 2634};
2635 2635
2636static struct snd_kcontrol_new snd_trident_vol_wave_control = 2636static const struct snd_kcontrol_new snd_trident_vol_wave_control =
2637{ 2637{
2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2639 .name = "Wave Playback Volume", 2639 .name = "Wave Playback Volume",
@@ -2700,7 +2700,7 @@ static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
2700 return change; 2700 return change;
2701} 2701}
2702 2702
2703static struct snd_kcontrol_new snd_trident_pcm_vol_control = 2703static const struct snd_kcontrol_new snd_trident_pcm_vol_control =
2704{ 2704{
2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2706 .name = "PCM Front Playback Volume", 2706 .name = "PCM Front Playback Volume",
@@ -2764,7 +2764,7 @@ static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
2764 return change; 2764 return change;
2765} 2765}
2766 2766
2767static struct snd_kcontrol_new snd_trident_pcm_pan_control = 2767static const struct snd_kcontrol_new snd_trident_pcm_pan_control =
2768{ 2768{
2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2770 .name = "PCM Pan Playback Control", 2770 .name = "PCM Pan Playback Control",
@@ -2821,7 +2821,7 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
2821 2821
2822static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); 2822static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
2823 2823
2824static struct snd_kcontrol_new snd_trident_pcm_rvol_control = 2824static const struct snd_kcontrol_new snd_trident_pcm_rvol_control =
2825{ 2825{
2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2827 .name = "PCM Reverb Playback Volume", 2827 .name = "PCM Reverb Playback Volume",
@@ -2877,7 +2877,7 @@ static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
2877 return change; 2877 return change;
2878} 2878}
2879 2879
2880static struct snd_kcontrol_new snd_trident_pcm_cvol_control = 2880static const struct snd_kcontrol_new snd_trident_pcm_cvol_control =
2881{ 2881{
2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2883 .name = "PCM Chorus Playback Volume", 2883 .name = "PCM Chorus Playback Volume",
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 2d8c14e3f8d2..d078e86414c2 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1683,7 +1683,7 @@ static int snd_via8233_dxs3_spdif_put(struct snd_kcontrol *kcontrol,
1683 return 0; 1683 return 0;
1684} 1684}
1685 1685
1686static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = { 1686static const struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = {
1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1689 .info = snd_via8233_dxs3_spdif_info, 1689 .info = snd_via8233_dxs3_spdif_info,
@@ -1772,7 +1772,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
1772 1772
1773static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1); 1773static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
1774 1774
1775static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = { 1775static const struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
1776 .name = "PCM Playback Volume", 1776 .name = "PCM Playback Volume",
1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1783,7 +1783,7 @@ static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
1783 .tlv = { .p = db_scale_dxs } 1783 .tlv = { .p = db_scale_dxs }
1784}; 1784};
1785 1785
1786static struct snd_kcontrol_new snd_via8233_dxs_volume_control = { 1786static const struct snd_kcontrol_new snd_via8233_dxs_volume_control = {
1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1788 .device = 0, 1788 .device = 0,
1789 /* .subdevice set later */ 1789 /* .subdevice set later */
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 8e457ea27f89..7df1663ea510 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -945,7 +945,7 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
945 return 0; 945 return 0;
946} 946}
947 947
948static struct snd_kcontrol_new vx_control_input_level = { 948static const struct snd_kcontrol_new vx_control_input_level = {
949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
951 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 951 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -956,7 +956,7 @@ static struct snd_kcontrol_new vx_control_input_level = {
956 .tlv = { .p = db_scale_mic }, 956 .tlv = { .p = db_scale_mic },
957}; 957};
958 958
959static struct snd_kcontrol_new vx_control_mic_level = { 959static const struct snd_kcontrol_new vx_control_mic_level = {
960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
962 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 962 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index ffee284898b3..fe4ba463b57c 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1316,7 +1316,7 @@ static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,
1316 return change; 1316 return change;
1317} 1317}
1318 1318
1319static struct snd_kcontrol_new snd_ymfpci_spdif_default = 1319static const struct snd_kcontrol_new snd_ymfpci_spdif_default =
1320{ 1320{
1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1344,7 +1344,7 @@ static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,
1344 return 0; 1344 return 0;
1345} 1345}
1346 1346
1347static struct snd_kcontrol_new snd_ymfpci_spdif_mask = 1347static const struct snd_kcontrol_new snd_ymfpci_spdif_mask =
1348{ 1348{
1349 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1349 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1391,7 +1391,7 @@ static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,
1391 return change; 1391 return change;
1392} 1392}
1393 1393
1394static struct snd_kcontrol_new snd_ymfpci_spdif_stream = 1394static const struct snd_kcontrol_new snd_ymfpci_spdif_stream =
1395{ 1395{
1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1439,7 +1439,7 @@ static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_
1439 return reg != old_reg; 1439 return reg != old_reg;
1440} 1440}
1441 1441
1442static struct snd_kcontrol_new snd_ymfpci_drec_source = { 1442static const struct snd_kcontrol_new snd_ymfpci_drec_source = {
1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1445 .name = "Direct Recording Source", 1445 .name = "Direct Recording Source",
@@ -1609,7 +1609,7 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1609 return change; 1609 return change;
1610} 1610}
1611 1611
1612static struct snd_kcontrol_new snd_ymfpci_dup4ch = { 1612static const struct snd_kcontrol_new snd_ymfpci_dup4ch = {
1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1614 .name = "4ch Duplication", 1614 .name = "4ch Duplication",
1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -1712,7 +1712,7 @@ static int snd_ymfpci_gpio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
1712 return 0; 1712 return 0;
1713} 1713}
1714 1714
1715static struct snd_kcontrol_new snd_ymfpci_rear_shared = { 1715static const struct snd_kcontrol_new snd_ymfpci_rear_shared = {
1716 .name = "Shared Rear/Line-In Switch", 1716 .name = "Shared Rear/Line-In Switch",
1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1718 .info = snd_ymfpci_gpio_sw_info, 1718 .info = snd_ymfpci_gpio_sw_info,
@@ -1776,7 +1776,7 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
1776 return 0; 1776 return 0;
1777} 1777}
1778 1778
1779static struct snd_kcontrol_new snd_ymfpci_pcm_volume = { 1779static const struct snd_kcontrol_new snd_ymfpci_pcm_volume = {
1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1781 .name = "PCM Playback Volume", 1781 .name = "PCM Playback Volume",
1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index bbef77d2b917..8e2878012d53 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -27,27 +27,6 @@
27 27
28#define SKL_SUSPEND_DELAY 2000 28#define SKL_SUSPEND_DELAY 2000
29 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 30#define AZX_PCIREG_PGCTL 0x44
52#define AZX_PGCTL_LSRMD_MASK (1 << 4) 31#define AZX_PGCTL_LSRMD_MASK (1 << 4)
53#define AZX_PCIREG_CGCTL 0x48 32#define AZX_PCIREG_CGCTL 0x48
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index ac75816ada7c..850fab4a8f3b 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -225,9 +225,9 @@ snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { 225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
226 struct soundfont_patch_info patch; 226 struct soundfont_patch_info patch;
227 if (count < (int)sizeof(patch)) 227 if (count < (int)sizeof(patch))
228 rc = -EINVAL; 228 return -EINVAL;
229 if (copy_from_user(&patch, buf, sizeof(patch))) 229 if (copy_from_user(&patch, buf, sizeof(patch)))
230 rc = -EFAULT; 230 return -EFAULT;
231 if (patch.type >= SNDRV_SFNT_LOAD_INFO && 231 if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
232 patch.type <= SNDRV_SFNT_PROBE_DATA) 232 patch.type <= SNDRV_SFNT_PROBE_DATA)
233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port)); 233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
diff --git a/sound/usb/card.c b/sound/usb/card.c
index f36cb068dad3..6640277a725b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -332,6 +332,7 @@ static int snd_usb_audio_dev_free(struct snd_device *device)
332static int snd_usb_audio_create(struct usb_interface *intf, 332static int snd_usb_audio_create(struct usb_interface *intf,
333 struct usb_device *dev, int idx, 333 struct usb_device *dev, int idx,
334 const struct snd_usb_audio_quirk *quirk, 334 const struct snd_usb_audio_quirk *quirk,
335 unsigned int usb_id,
335 struct snd_usb_audio **rchip) 336 struct snd_usb_audio **rchip)
336{ 337{
337 struct snd_card *card; 338 struct snd_card *card;
@@ -381,8 +382,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
381 atomic_set(&chip->usage_count, 0); 382 atomic_set(&chip->usage_count, 0);
382 atomic_set(&chip->shutdown, 0); 383 atomic_set(&chip->shutdown, 0);
383 384
384 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 385 chip->usb_id = usb_id;
385 le16_to_cpu(dev->descriptor.idProduct));
386 INIT_LIST_HEAD(&chip->pcm_list); 386 INIT_LIST_HEAD(&chip->pcm_list);
387 INIT_LIST_HEAD(&chip->ep_list); 387 INIT_LIST_HEAD(&chip->ep_list);
388 INIT_LIST_HEAD(&chip->midi_list); 388 INIT_LIST_HEAD(&chip->midi_list);
@@ -569,7 +569,7 @@ static int usb_audio_probe(struct usb_interface *intf,
569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && 569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { 570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
571 err = snd_usb_audio_create(intf, dev, i, quirk, 571 err = snd_usb_audio_create(intf, dev, i, quirk,
572 &chip); 572 id, &chip);
573 if (err < 0) 573 if (err < 0)
574 goto __error; 574 goto __error;
575 chip->pm_intf = intf; 575 chip->pm_intf = intf;
diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c
index fab53f58d447..b3854f8c0c67 100644
--- a/sound/usb/line6/pcm.c
+++ b/sound/usb/line6/pcm.c
@@ -430,7 +430,7 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
430} 430}
431 431
432/* control definition */ 432/* control definition */
433static struct snd_kcontrol_new line6_controls[] = { 433static const struct snd_kcontrol_new line6_controls[] = {
434 { 434 {
435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
436 .name = "PCM Playback Volume", 436 .name = "PCM Playback Volume",
diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
index 17aa616e61f5..358224cc5638 100644
--- a/sound/usb/line6/pod.c
+++ b/sound/usb/line6/pod.c
@@ -380,7 +380,7 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
380} 380}
381 381
382/* control definition */ 382/* control definition */
383static struct snd_kcontrol_new pod_control_monitor = { 383static const struct snd_kcontrol_new pod_control_monitor = {
384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 .name = "Monitor Playback Volume", 385 .name = "Monitor Playback Volume",
386 .index = 0, 386 .index = 0,
diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c
index 8e22f430d700..ba7975c0d03d 100644
--- a/sound/usb/line6/toneport.c
+++ b/sound/usb/line6/toneport.c
@@ -250,7 +250,7 @@ static void toneport_start_pcm(unsigned long arg)
250} 250}
251 251
252/* control definition */ 252/* control definition */
253static struct snd_kcontrol_new toneport_control_monitor = { 253static const struct snd_kcontrol_new toneport_control_monitor = {
254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
255 .name = "Monitor Playback Volume", 255 .name = "Monitor Playback Volume",
256 .index = 0, 256 .index = 0,
@@ -261,7 +261,7 @@ static struct snd_kcontrol_new toneport_control_monitor = {
261}; 261};
262 262
263/* source selector definition */ 263/* source selector definition */
264static struct snd_kcontrol_new toneport_control_source = { 264static const struct snd_kcontrol_new toneport_control_source = {
265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
266 .name = "PCM Capture Source", 266 .name = "PCM Capture Source",
267 .index = 0, 267 .index = 0,
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 6e763bc8d7db..a35f41467237 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1922,7 +1922,7 @@ static int roland_load_put(struct snd_kcontrol *kcontrol,
1922 return changed; 1922 return changed;
1923} 1923}
1924 1924
1925static struct snd_kcontrol_new roland_load_ctl = { 1925static const struct snd_kcontrol_new roland_load_ctl = {
1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1927 .name = "MIDI Input Mode", 1927 .name = "MIDI Input Mode",
1928 .info = roland_load_info, 1928 .info = roland_load_info,
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4703caea56b2..082736c539bc 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1172,7 +1172,7 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
1172}; 1172};
1173 1173
1174/* the read-only variant */ 1174/* the read-only variant */
1175static struct snd_kcontrol_new usb_feature_unit_ctl_ro = { 1175static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1177 .name = "", /* will be filled later manually */ 1177 .name = "", /* will be filled later manually */
1178 .info = mixer_ctl_feature_info, 1178 .info = mixer_ctl_feature_info,
@@ -1745,7 +1745,7 @@ static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
1745} 1745}
1746 1746
1747/* alsa control interface for processing/extension unit */ 1747/* alsa control interface for processing/extension unit */
1748static struct snd_kcontrol_new mixer_procunit_ctl = { 1748static const struct snd_kcontrol_new mixer_procunit_ctl = {
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "", /* will be filled later */ 1750 .name = "", /* will be filled later */
1751 .info = mixer_ctl_feature_info, 1751 .info = mixer_ctl_feature_info,
@@ -2033,7 +2033,7 @@ static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
2033} 2033}
2034 2034
2035/* alsa control interface for selector unit */ 2035/* alsa control interface for selector unit */
2036static struct snd_kcontrol_new mixer_selectunit_ctl = { 2036static const struct snd_kcontrol_new mixer_selectunit_ctl = {
2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2038 .name = "", /* will be filled later */ 2038 .name = "", /* will be filled later */
2039 .info = mixer_ctl_selector_info, 2039 .info = mixer_ctl_selector_info,
diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c
index 7438e7c4a842..c33e2378089d 100644
--- a/sound/usb/mixer_scarlett.c
+++ b/sound/usb/mixer_scarlett.c
@@ -477,7 +477,7 @@ static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
477 return 0; 477 return 0;
478} 478}
479 479
480static struct snd_kcontrol_new usb_scarlett_ctl_switch = { 480static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482 .name = "", 482 .name = "",
483 .info = scarlett_ctl_switch_info, 483 .info = scarlett_ctl_switch_info,
@@ -487,7 +487,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_switch = {
487 487
488static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0); 488static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
489 489
490static struct snd_kcontrol_new usb_scarlett_ctl = { 490static const struct snd_kcontrol_new usb_scarlett_ctl = {
491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
493 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 493 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -499,7 +499,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl = {
499 .tlv = { .p = db_scale_scarlett_gain } 499 .tlv = { .p = db_scale_scarlett_gain }
500}; 500};
501 501
502static struct snd_kcontrol_new usb_scarlett_ctl_master = { 502static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
505 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 505 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -511,7 +511,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_master = {
511 .tlv = { .p = db_scale_scarlett_gain } 511 .tlv = { .p = db_scale_scarlett_gain }
512}; 512};
513 513
514static struct snd_kcontrol_new usb_scarlett_ctl_enum = { 514static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
516 .name = "", 516 .name = "",
517 .info = scarlett_ctl_enum_info, 517 .info = scarlett_ctl_enum_info,
@@ -519,7 +519,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_enum = {
519 .put = scarlett_ctl_enum_put, 519 .put = scarlett_ctl_enum_put,
520}; 520};
521 521
522static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = { 522static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
524 .name = "", 524 .name = "",
525 .info = scarlett_ctl_enum_dynamic_info, 525 .info = scarlett_ctl_enum_dynamic_info,
@@ -527,7 +527,7 @@ static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
527 .put = scarlett_ctl_enum_put, 527 .put = scarlett_ctl_enum_put,
528}; 528};
529 529
530static struct snd_kcontrol_new usb_scarlett_ctl_sync = { 530static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
533 .name = "", 533 .name = "",
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index cf45bf1f7ee0..e118bdca983d 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -472,7 +472,7 @@ static int usb_stream_hwdep_new(struct snd_card *card)
472 hw->ops.mmap = usb_stream_hwdep_mmap; 472 hw->ops.mmap = usb_stream_hwdep_mmap;
473 hw->ops.poll = usb_stream_hwdep_poll; 473 hw->ops.poll = usb_stream_hwdep_poll;
474 474
475 sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", 475 sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm",
476 dev->bus->busnum, dev->devnum); 476 dev->bus->busnum, dev->devnum);
477 return 0; 477 return 0;
478} 478}
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 605e1047c01d..f4b3cda412fc 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -258,7 +258,7 @@ int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
258 hw->ops.mmap = snd_us428ctls_mmap; 258 hw->ops.mmap = snd_us428ctls_mmap;
259 hw->ops.poll = snd_us428ctls_poll; 259 hw->ops.poll = snd_us428ctls_poll;
260 hw->exclusive = 1; 260 hw->exclusive = 1;
261 sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); 261 sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
262 return 0; 262 return 0;
263} 263}
264 264
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index f95164b91152..d51c7fd7835b 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -723,7 +723,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
723 hw->ops.release = snd_usX2Y_hwdep_pcm_release; 723 hw->ops.release = snd_usX2Y_hwdep_pcm_release;
724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap; 724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
725 hw->exclusive = 1; 725 hw->exclusive = 1;
726 sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum); 726 sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
727 727
728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm); 728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
729 if (err < 0) { 729 if (err < 0) {