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)  * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
^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/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "xonar.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static void hdmi_write_command(struct oxygen *chip, u8 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 			       unsigned int count, const u8 *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	u8 checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	oxygen_write_uart(chip, 0xfb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	oxygen_write_uart(chip, 0xef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	oxygen_write_uart(chip, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	oxygen_write_uart(chip, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	for (i = 0; i < count; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		oxygen_write_uart(chip, params[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	checksum = 0xfb + 0xef + command + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	for (i = 0; i < count; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		checksum += params[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	oxygen_write_uart(chip, checksum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static void xonar_hdmi_init_commands(struct oxygen *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 				     struct xonar_hdmi *hdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	u8 param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	oxygen_reset_uart(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	param = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	hdmi_write_command(chip, 0x61, 1, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	param = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	hdmi_write_command(chip, 0x74, 1, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	hdmi_write_command(chip, 0x54, 5, hdmi->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *hdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	hdmi->params[1] = IEC958_AES3_CON_FS_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	hdmi->params[4] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	xonar_hdmi_init_commands(chip, hdmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) void xonar_hdmi_cleanup(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u8 param = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	hdmi_write_command(chip, 0x74, 1, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	xonar_hdmi_init_commands(chip, hdmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) void xonar_hdmi_pcm_hardware_filter(unsigned int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				    struct snd_pcm_hardware *hardware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (channel == PCM_MULTICH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		hardware->rates = SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				  SNDRV_PCM_RATE_48000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				  SNDRV_PCM_RATE_96000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				  SNDRV_PCM_RATE_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		hardware->rate_min = 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			   struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	hdmi->params[0] = 0; /* 1 = non-audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	switch (params_rate(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		hdmi->params[1] = IEC958_AES3_CON_FS_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		hdmi->params[1] = IEC958_AES3_CON_FS_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	default: /* 96000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		hdmi->params[1] = IEC958_AES3_CON_FS_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		hdmi->params[1] = IEC958_AES3_CON_FS_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	hdmi->params[2] = params_channels(params) / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		hdmi->params[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		hdmi->params[3] = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	hdmi->params[4] = 1; /* ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	hdmi_write_command(chip, 0x54, 5, hdmi->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) void xonar_hdmi_uart_input(struct oxygen *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (chip->uart_input_count >= 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	    chip->uart_input[chip->uart_input_count - 2] == 'O' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	    chip->uart_input[chip->uart_input_count - 1] == 'K') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		dev_dbg(chip->card->dev, "message from HDMI chip received:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				     chip->uart_input, chip->uart_input_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		chip->uart_input_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }