diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 995c2cefc222b1e67d4d92e0970844b0e1a82798..4f39ef924a1a1982abd05393ab86b465eea0d988 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -165,5 +165,6 @@ config SND_FIREFACE
 	  * Fireface 400
 	  * Fireface 800
 	  * Fireface UCX
+	  * Fireface 802
 
 endif # SND_FIREWIRE
diff --git a/sound/firewire/fireface/ff-protocol-latter.c b/sound/firewire/fireface/ff-protocol-latter.c
index 76ae568489ef10e37a2123ebf714c896dc139d21..ea885e72595035b0940660a6f66a779965822cfa 100644
--- a/sound/firewire/fireface/ff-protocol-latter.c
+++ b/sound/firewire/fireface/ff-protocol-latter.c
@@ -16,7 +16,8 @@
 #define LATTER_SYNC_STATUS	0x0000801c0000ULL
 
 static int parse_clock_bits(u32 data, unsigned int *rate,
-			    enum snd_ff_clock_src *src)
+			    enum snd_ff_clock_src *src,
+			    enum snd_ff_unit_version unit_version)
 {
 	static const struct {
 		unsigned int rate;
@@ -43,6 +44,11 @@ static int parse_clock_bits(u32 data, unsigned int *rate,
 	};
 	int i;
 
+	if (unit_version != SND_FF_UNIT_VERSION_UCX) {
+		// e.g. 0x00fe0f20 but expected 0x00eff002.
+		data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4);
+	}
+
 	for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) {
 		rate_entry = rate_entries + i;
 		if ((data & 0x0f000000) == rate_entry->flag) {
@@ -79,7 +85,7 @@ static int latter_get_clock(struct snd_ff *ff, unsigned int *rate,
 		return err;
 	data = le32_to_cpu(reg);
 
-	return parse_clock_bits(data, rate, src);
+	return parse_clock_bits(data, rate, src, ff->unit_version);
 }
 
 static int latter_switch_fetching_mode(struct snd_ff *ff, bool enable)
@@ -181,14 +187,30 @@ static int latter_begin_session(struct snd_ff *ff, unsigned int rate)
 	__le32 reg;
 	int err;
 
-	if (rate >= 32000 && rate <= 48000)
-		flag = 0x92;
-	else if (rate >= 64000 && rate <= 96000)
-		flag = 0x8e;
-	else if (rate >= 128000 && rate <= 192000)
-		flag = 0x8c;
-	else
-		return -EINVAL;
+	if (ff->unit_version == SND_FF_UNIT_VERSION_UCX) {
+		// For Fireface UCX. Always use the maximum number of data
+		// channels in data block of packet.
+		if (rate >= 32000 && rate <= 48000)
+			flag = 0x92;
+		else if (rate >= 64000 && rate <= 96000)
+			flag = 0x8e;
+		else if (rate >= 128000 && rate <= 192000)
+			flag = 0x8c;
+		else
+			return -EINVAL;
+	} else {
+		// For Fireface 802. Due to bandwidth limitation on
+		// IEEE 1394a (400 Mbps), Analog 1-12 and AES are available
+		// without any ADAT at quadruple speed.
+		if (rate >= 32000 && rate <= 48000)
+			flag = 0x9e;
+		else if (rate >= 64000 && rate <= 96000)
+			flag = 0x96;
+		else if (rate >= 128000 && rate <= 192000)
+			flag = 0x8e;
+		else
+			return -EINVAL;
+	}
 
 	if (generation != fw_parent_device(ff->unit)->card->generation) {
 		err = fw_iso_resources_update(&ff->tx_resources);
@@ -207,8 +229,6 @@ static int latter_begin_session(struct snd_ff *ff, unsigned int rate)
 	if (err < 0)
 		return err;
 
-	// Always use the maximum number of data channels in data block of
-	// packet.
 	reg = cpu_to_le32(flag);
 	return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
 				  LATTER_ISOC_START, &reg, sizeof(reg), 0);
@@ -263,7 +283,7 @@ static void latter_dump_status(struct snd_ff *ff, struct snd_info_buffer *buffer
 		}
 	}
 
-	err = parse_clock_bits(data, &rate, &src);
+	err = parse_clock_bits(data, &rate, &src, ff->unit_version);
 	if (err < 0)
 		return;
 	label = snd_ff_proc_get_clk_label(src);
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
index dd3cd25f2e3b19e46245af4167abb1c05a223b85..e4140116f3cc7b92253737e2c3e5563a4091bd4c 100644
--- a/sound/firewire/fireface/ff.c
+++ b/sound/firewire/fireface/ff.c
@@ -20,6 +20,7 @@ static void name_card(struct snd_ff *ff)
 		[SND_FF_UNIT_VERSION_FF800]	= "Fireface800",
 		[SND_FF_UNIT_VERSION_FF400]	= "Fireface400",
 		[SND_FF_UNIT_VERSION_UCX]	= "FirefaceUCX",
+		[SND_FF_UNIT_VERSION_802]	= "Fireface802",
 	};
 	const char *name;
 
@@ -186,6 +187,17 @@ static const struct snd_ff_spec spec_ucx = {
 	.midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
 };
 
+static const struct snd_ff_spec spec_802 = {
+	.pcm_capture_channels = {30, 22, 14},
+	.pcm_playback_channels = {30, 22, 14},
+	.midi_in_ports = 1,
+	.midi_out_ports = 1,
+	.protocol = &snd_ff_protocol_latter,
+	.midi_high_addr = 0xffff00000034ull,
+	.midi_addr_range = 0x80,
+	.midi_rx_addrs = {0xffff00000030ull, 0xffff00000030ull},
+};
+
 static const struct ieee1394_device_id snd_ff_id_table[] = {
 	/* Fireface 800 */
 	{
@@ -223,6 +235,18 @@ static const struct ieee1394_device_id snd_ff_id_table[] = {
 		.model_id	= 0x101800,
 		.driver_data	= (kernel_ulong_t)&spec_ucx,
 	},
+	// Fireface 802.
+	{
+		.match_flags	= IEEE1394_MATCH_VENDOR_ID |
+				  IEEE1394_MATCH_SPECIFIER_ID |
+				  IEEE1394_MATCH_VERSION |
+				  IEEE1394_MATCH_MODEL_ID,
+		.vendor_id	= OUI_RME,
+		.specifier_id	= OUI_RME,
+		.version	= SND_FF_UNIT_VERSION_802,
+		.model_id	= 0x101800,
+		.driver_data	= (kernel_ulong_t)&spec_802,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
index 0c4fe7cff84ddd8d212b3c830a65e90265e4181b..1282a57c009f9a039fc390102752be2c75a7f616 100644
--- a/sound/firewire/fireface/ff.h
+++ b/sound/firewire/fireface/ff.h
@@ -38,6 +38,7 @@ enum snd_ff_unit_version {
 	SND_FF_UNIT_VERSION_FF800	= 0x000001,
 	SND_FF_UNIT_VERSION_FF400	= 0x000002,
 	SND_FF_UNIT_VERSION_UCX		= 0x000004,
+	SND_FF_UNIT_VERSION_802		= 0x000005,
 };
 
 enum snd_ff_stream_mode {