Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * motu-protocol-v3.c - a part of driver for MOTU FireWire series
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "motu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define V3_CLOCK_STATUS_OFFSET		0x0b14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define  V3_FETCH_PCM_FRAMES		0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define  V3_CLOCK_RATE_MASK		0x0000ff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define  V3_CLOCK_RATE_SHIFT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define  V3_CLOCK_SOURCE_MASK		0x000000ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define V3_OPT_IFACE_MODE_OFFSET	0x0c94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define  V3_ENABLE_OPT_IN_IFACE_A	0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define  V3_ENABLE_OPT_IN_IFACE_B	0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define  V3_ENABLE_OPT_OUT_IFACE_A	0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define  V3_ENABLE_OPT_OUT_IFACE_B	0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define  V3_NO_ADAT_OPT_IN_IFACE_A	0x00010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define  V3_NO_ADAT_OPT_IN_IFACE_B	0x00100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define  V3_NO_ADAT_OPT_OUT_IFACE_A	0x00040000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define  V3_NO_ADAT_OPT_OUT_IFACE_B	0x00400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define V3_MSG_FLAG_CLK_CHANGED		0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define V3_CLK_WAIT_MSEC		4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 					unsigned int *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	data = (data & V3_CLOCK_RATE_MASK) >> V3_CLOCK_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if (data >= ARRAY_SIZE(snd_motu_clock_rates))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	*rate = snd_motu_clock_rates[data];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 					unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	bool need_to_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		if (snd_motu_clock_rates[i] == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (i == ARRAY_SIZE(snd_motu_clock_rates))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	data &= ~(V3_CLOCK_RATE_MASK | V3_FETCH_PCM_FRAMES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	data |= i << V3_CLOCK_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	need_to_wait = data != be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	reg = cpu_to_be32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	err = snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 					 sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (need_to_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		motu->msg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		result = wait_event_interruptible_timeout(motu->hwdep_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 					motu->msg & V3_MSG_FLAG_CLK_CHANGED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					msecs_to_jiffies(V3_CLK_WAIT_MSEC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 				      enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	switch (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		*src = SND_MOTU_CLOCK_SOURCE_SPH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	case 0x18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	case 0x19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		u32 options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		err = snd_motu_transaction_read(motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				V3_OPT_IFACE_MODE_OFFSET, &reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		options = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (data == 0x18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			if (options & V3_NO_ADAT_OPT_IN_IFACE_A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			if (options & V3_NO_ADAT_OPT_IN_IFACE_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 				*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		*src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int v3_detect_clock_source(struct snd_motu *motu, u32 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				  enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	switch (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		*src = SND_MOTU_CLOCK_SOURCE_SPH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		*src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 					  enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (motu->spec == &snd_motu_spec_828mk3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		return detect_clock_source_828mk3(motu, data, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return v3_detect_clock_source(motu, data, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 					      bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		data |= V3_FETCH_PCM_FRAMES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		data &= ~V3_FETCH_PCM_FRAMES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	reg = cpu_to_be32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 					  sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int detect_packet_formats_828mk3(struct snd_motu *motu, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (data & V3_ENABLE_OPT_IN_IFACE_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		if (data & V3_NO_ADAT_OPT_IN_IFACE_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			motu->tx_packet_formats.pcm_chunks[0] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			motu->tx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			motu->tx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			motu->tx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (data & V3_ENABLE_OPT_IN_IFACE_B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		if (data & V3_NO_ADAT_OPT_IN_IFACE_B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			motu->tx_packet_formats.pcm_chunks[0] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			motu->tx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			motu->tx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			motu->tx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (data & V3_ENABLE_OPT_OUT_IFACE_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		if (data & V3_NO_ADAT_OPT_OUT_IFACE_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			motu->rx_packet_formats.pcm_chunks[0] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			motu->rx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (data & V3_ENABLE_OPT_OUT_IFACE_B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		if (data & V3_NO_ADAT_OPT_OUT_IFACE_B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			motu->rx_packet_formats.pcm_chunks[0] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			motu->rx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	motu->tx_packet_formats.pcm_byte_offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	motu->rx_packet_formats.pcm_byte_offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	motu->tx_packet_formats.msg_chunks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	motu->rx_packet_formats.msg_chunks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	memcpy(motu->tx_packet_formats.pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	       motu->spec->tx_fixed_pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	       sizeof(motu->tx_packet_formats.pcm_chunks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	memcpy(motu->rx_packet_formats.pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	       motu->spec->rx_fixed_pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	       sizeof(motu->rx_packet_formats.pcm_chunks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (motu->spec == &snd_motu_spec_828mk3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		return detect_packet_formats_828mk3(motu, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) const struct snd_motu_spec snd_motu_spec_828mk3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	.name = "828mk3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.protocol_version = SND_MOTU_PROTOCOL_V3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.flags = SND_MOTU_SPEC_RX_MIDI_3RD_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		 SND_MOTU_SPEC_TX_MIDI_3RD_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.tx_fixed_pcm_chunks = {18, 18, 14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.rx_fixed_pcm_chunks = {14, 14, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) const struct snd_motu_spec snd_motu_spec_ultralite_mk3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.name = "UltraLiteMk3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.protocol_version = SND_MOTU_PROTOCOL_V3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	.flags = SND_MOTU_SPEC_RX_MIDI_3RD_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		 SND_MOTU_SPEC_TX_MIDI_3RD_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	.tx_fixed_pcm_chunks = {18, 14, 10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	.rx_fixed_pcm_chunks = {14, 14, 14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) const struct snd_motu_spec snd_motu_spec_audio_express = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	.name = "AudioExpress",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	.protocol_version = SND_MOTU_PROTOCOL_V3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		 SND_MOTU_SPEC_TX_MIDI_3RD_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	.tx_fixed_pcm_chunks = {10, 10, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	.rx_fixed_pcm_chunks = {10, 10, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const struct snd_motu_spec snd_motu_spec_4pre = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	.name = "4pre",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	.protocol_version = SND_MOTU_PROTOCOL_V3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	.tx_fixed_pcm_chunks = {10, 10, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.rx_fixed_pcm_chunks = {10, 10, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };