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-v2.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 "motu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define V2_CLOCK_STATUS_OFFSET			0x0b14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define  V2_CLOCK_RATE_MASK			0x00000038
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define  V2_CLOCK_RATE_SHIFT			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define  V2_CLOCK_SRC_MASK			0x00000007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define  V2_CLOCK_SRC_SHIFT			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define  V2_CLOCK_FETCH_ENABLE			0x02000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define  V2_CLOCK_MODEL_SPECIFIC		0x04000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define V2_IN_OUT_CONF_OFFSET			0x0c04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define  V2_OPT_OUT_IFACE_MASK			0x00000c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define  V2_OPT_OUT_IFACE_SHIFT			10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define  V2_OPT_IN_IFACE_MASK			0x00000300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define  V2_OPT_IN_IFACE_SHIFT			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define  V2_OPT_IFACE_MODE_NONE			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define  V2_OPT_IFACE_MODE_ADAT			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define  V2_OPT_IFACE_MODE_SPDIF		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static int get_clock_rate(u32 data, unsigned int *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned int index = (data & V2_CLOCK_RATE_MASK) >> V2_CLOCK_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	if (index >= ARRAY_SIZE(snd_motu_clock_rates))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	*rate = snd_motu_clock_rates[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 					unsigned int *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	return get_clock_rate(be32_to_cpu(reg), rate);
^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_v2_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) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int 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, V2_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 &= ~V2_CLOCK_RATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	data |= i << V2_CLOCK_RATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	reg = cpu_to_be32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 					  sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 					     enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	switch (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		// To check the configuration of optical interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		int err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == V2_OPT_IFACE_MODE_SPDIF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		*src = SND_MOTU_CLOCK_SOURCE_SPH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		*src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int v2_detect_clock_source(struct snd_motu *motu, u32 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				  enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	switch (data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		*src = SND_MOTU_CLOCK_SOURCE_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		*src = SND_MOTU_CLOCK_SOURCE_SPH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		*src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		*src = SND_MOTU_CLOCK_SOURCE_UNKNOWN;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int get_clock_source(struct snd_motu *motu, u32 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			    enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	data &= V2_CLOCK_SRC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (motu->spec == &snd_motu_spec_828mk2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	    motu->spec == &snd_motu_spec_traveler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return detect_clock_source_optical_model(motu, data, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return v2_detect_clock_source(motu, data, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 					  enum snd_motu_clock_source *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	return get_clock_source(motu, be32_to_cpu(reg), src);
^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) // Expected for Traveler and 896HD, which implements Altera Cyclone EP1C3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int switch_fetching_mode_cyclone(struct snd_motu *motu, u32 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 					bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	*data |= V2_CLOCK_MODEL_SPECIFIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) // For UltraLite and 8pre, which implements Xilinx Spartan XC3S200.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int switch_fetching_mode_spartan(struct snd_motu *motu, u32 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 					bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	enum snd_motu_clock_source src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	err = get_clock_source(motu, *data, &src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	err = get_clock_rate(*data, &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if (src == SND_MOTU_CLOCK_SOURCE_SPH && rate > 48000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		*data |= V2_CLOCK_MODEL_SPECIFIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 					      bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (motu->spec == &snd_motu_spec_828mk2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		// 828mkII implements Altera ACEX 1K EP1K30. Nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 						&reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		data &= ~(V2_CLOCK_FETCH_ENABLE | V2_CLOCK_MODEL_SPECIFIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			data |= V2_CLOCK_FETCH_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (motu->spec == &snd_motu_spec_traveler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			err = switch_fetching_mode_cyclone(motu, &data, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			err = switch_fetching_mode_spartan(motu, &data, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		reg = cpu_to_be32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 						  &reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int detect_packet_formats_828mk2(struct snd_motu *motu, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		motu->tx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		motu->tx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		motu->rx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int detect_packet_formats_traveler(struct snd_motu *motu, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		motu->tx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		motu->tx_packet_formats.pcm_chunks[1] += 4;
^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) 	if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		motu->rx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		motu->rx_packet_formats.pcm_chunks[1] += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int detect_packet_formats_8pre(struct snd_motu *motu, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		motu->tx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		motu->tx_packet_formats.pcm_chunks[1] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	    V2_OPT_IFACE_MODE_ADAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		motu->rx_packet_formats.pcm_chunks[0] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		motu->rx_packet_formats.pcm_chunks[1] += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	__be32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	motu->tx_packet_formats.pcm_byte_offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	motu->rx_packet_formats.pcm_byte_offset = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	motu->tx_packet_formats.msg_chunks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	motu->rx_packet_formats.msg_chunks = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 					sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	data = be32_to_cpu(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	memcpy(motu->tx_packet_formats.pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	       motu->spec->tx_fixed_pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	       sizeof(motu->tx_packet_formats.pcm_chunks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	memcpy(motu->rx_packet_formats.pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	       motu->spec->rx_fixed_pcm_chunks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	       sizeof(motu->rx_packet_formats.pcm_chunks));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (motu->spec == &snd_motu_spec_828mk2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return detect_packet_formats_828mk2(motu, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	else if (motu->spec == &snd_motu_spec_traveler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return detect_packet_formats_traveler(motu, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	else if (motu->spec == &snd_motu_spec_8pre)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		return detect_packet_formats_8pre(motu, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) const struct snd_motu_spec snd_motu_spec_828mk2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	.name = "828mk2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.protocol_version = SND_MOTU_PROTOCOL_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.tx_fixed_pcm_chunks = {14, 14, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.rx_fixed_pcm_chunks = {14, 14, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) const struct snd_motu_spec snd_motu_spec_traveler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.name = "Traveler",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.protocol_version = SND_MOTU_PROTOCOL_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	.tx_fixed_pcm_chunks = {14, 14, 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	.rx_fixed_pcm_chunks = {14, 14, 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) const struct snd_motu_spec snd_motu_spec_ultralite = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.name = "UltraLite",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	.protocol_version = SND_MOTU_PROTOCOL_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	.tx_fixed_pcm_chunks = {14, 14, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	.rx_fixed_pcm_chunks = {14, 14, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) const struct snd_motu_spec snd_motu_spec_8pre = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	.name = "8pre",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	.protocol_version = SND_MOTU_PROTOCOL_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	.flags = SND_MOTU_SPEC_RX_MIDI_2ND_Q |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		 SND_MOTU_SPEC_TX_MIDI_2ND_Q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	// Two dummy chunks always in the end of data block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	.tx_fixed_pcm_chunks = {10, 10, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	.rx_fixed_pcm_chunks = {6, 6, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };