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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * dice-extension.c - a part of driver for DICE based devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2018 Takashi Sakamoto
^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 "dice.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /* For TCD2210/2220, TCAT defines extension of application protocol. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define DICE_EXT_APP_SPACE		0xffffe0200000uLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define DICE_EXT_APP_CAPS_OFFSET	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define DICE_EXT_APP_CAPS_SIZE		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define DICE_EXT_APP_CMD_OFFSET		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define DICE_EXT_APP_CMD_SIZE		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define DICE_EXT_APP_MIXER_OFFSET	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define DICE_EXT_APP_MIXER_SIZE		0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define DICE_EXT_APP_PEAK_OFFSET	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define DICE_EXT_APP_PEAK_SIZE		0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define DICE_EXT_APP_ROUTER_OFFSET	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define DICE_EXT_APP_ROUTER_SIZE	0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DICE_EXT_APP_STREAM_OFFSET	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DICE_EXT_APP_STREAM_SIZE	0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DICE_EXT_APP_CURRENT_OFFSET	0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DICE_EXT_APP_CURRENT_SIZE	0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define DICE_EXT_APP_STANDALONE_OFFSET	0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define DICE_EXT_APP_STANDALONE_SIZE	0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define DICE_EXT_APP_APPLICATION_OFFSET	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define DICE_EXT_APP_APPLICATION_SIZE	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define EXT_APP_STREAM_TX_NUMBER	0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define EXT_APP_STREAM_RX_NUMBER	0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define EXT_APP_STREAM_ENTRIES		0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define EXT_APP_STREAM_ENTRY_SIZE	0x010c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define  EXT_APP_NUMBER_AUDIO		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define  EXT_APP_NUMBER_MIDI		0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define  EXT_APP_NAMES			0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define   EXT_APP_NAMES_SIZE		256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define  EXT_APP_AC3			0x0108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define EXT_APP_CONFIG_LOW_ROUTER	0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define EXT_APP_CONFIG_LOW_STREAM	0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define EXT_APP_CONFIG_MIDDLE_ROUTER	0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define EXT_APP_CONFIG_MIDDLE_STREAM	0x3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define EXT_APP_CONFIG_HIGH_ROUTER	0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define EXT_APP_CONFIG_HIGH_STREAM	0x5000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static inline int read_transaction(struct snd_dice *dice, u64 section_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 				   u32 offset, void *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return snd_fw_transaction(dice->unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				  len == 4 ? TCODE_READ_QUADLET_REQUEST :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 					     TCODE_READ_BLOCK_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 				  section_addr + offset, buf, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static int read_stream_entries(struct snd_dice *dice, u64 section_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			       u32 base_offset, unsigned int stream_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			       unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			       unsigned int pcm_channels[MAX_STREAMS][3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			       unsigned int midi_ports[MAX_STREAMS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	u32 entry_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	__be32 reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	for (i = 0; i < stream_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		entry_offset = base_offset + i * EXT_APP_STREAM_ENTRY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		err = read_transaction(dice, section_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				    entry_offset + EXT_APP_NUMBER_AUDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				    reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		pcm_channels[i][mode] = be32_to_cpu(reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		midi_ports[i] = max(midi_ports[i], be32_to_cpu(reg[1]));
^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) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static int detect_stream_formats(struct snd_dice *dice, u64 section_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u32 base_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	__be32 reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	unsigned int stream_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	for (mode = 0; mode < SND_DICE_RATE_MODE_COUNT; ++mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		unsigned int cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		 * Some models report stream formats at highest mode, however
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		 * they don't support the mode. Check clock capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (mode == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			cap = CLOCK_CAP_RATE_176400 | CLOCK_CAP_RATE_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		} else if (mode == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			cap = CLOCK_CAP_RATE_88200 | CLOCK_CAP_RATE_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			cap = CLOCK_CAP_RATE_32000 | CLOCK_CAP_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			      CLOCK_CAP_RATE_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		if (!(cap & dice->clock_caps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		base_offset = 0x2000 * mode + 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		err = read_transaction(dice, section_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 				       base_offset + EXT_APP_STREAM_TX_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				       &reg, sizeof(reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		base_offset += EXT_APP_STREAM_ENTRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		stream_count = be32_to_cpu(reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		err = read_stream_entries(dice, section_addr, base_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 					  stream_count, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 					  dice->tx_pcm_chs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 					  dice->tx_midi_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		base_offset += stream_count * EXT_APP_STREAM_ENTRY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		stream_count = be32_to_cpu(reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		err = read_stream_entries(dice, section_addr, base_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 					  stream_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 					  mode, dice->rx_pcm_chs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 					  dice->rx_midi_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int snd_dice_detect_extension_formats(struct snd_dice *dice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	__be32 *pointers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	u64 section_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	pointers = kmalloc_array(9, sizeof(__be32) * 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (pointers == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				 DICE_EXT_APP_SPACE, pointers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				 9 * sizeof(__be32) * 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	/* Check two of them for offset have the same value or not. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	for (i = 0; i < 9; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		for (j = i + 1; j < 9; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			if (pointers[i * 2] == pointers[j * 2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				// Fallback to limited functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				err = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	section_addr = DICE_EXT_APP_SPACE + be32_to_cpu(pointers[12]) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	err = detect_stream_formats(dice, section_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	kfree(pointers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }