1 /* 2 * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim) 3 * 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 5 * 6 * 7 * This driver is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License, version 2. 9 * 10 * This driver is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this driver; if not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <linux/pci.h> 20 #include <linux/delay.h> 21 #include <sound/asoundef.h> 22 #include <sound/control.h> 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/tlv.h> 27 #include "xonar.h" 28 29 static void hdmi_write_command(struct oxygen *chip, u8 command, 30 unsigned int count, const u8 *params) 31 { 32 unsigned int i; 33 u8 checksum; 34 35 oxygen_write_uart(chip, 0xfb); 36 oxygen_write_uart(chip, 0xef); 37 oxygen_write_uart(chip, command); 38 oxygen_write_uart(chip, count); 39 for (i = 0; i < count; ++i) 40 oxygen_write_uart(chip, params[i]); 41 checksum = 0xfb + 0xef + command + count; 42 for (i = 0; i < count; ++i) 43 checksum += params[i]; 44 oxygen_write_uart(chip, checksum); 45 } 46 47 static void xonar_hdmi_init_commands(struct oxygen *chip, 48 struct xonar_hdmi *hdmi) 49 { 50 u8 param; 51 52 oxygen_reset_uart(chip); 53 param = 0; 54 hdmi_write_command(chip, 0x61, 1, ¶m); 55 param = 1; 56 hdmi_write_command(chip, 0x74, 1, ¶m); 57 hdmi_write_command(chip, 0x54, 5, hdmi->params); 58 } 59 60 void xonar_hdmi_init(struct oxygen *chip, struct xonar_hdmi *hdmi) 61 { 62 hdmi->params[1] = IEC958_AES3_CON_FS_48000; 63 hdmi->params[4] = 1; 64 xonar_hdmi_init_commands(chip, hdmi); 65 } 66 67 void xonar_hdmi_cleanup(struct oxygen *chip) 68 { 69 u8 param = 0; 70 71 hdmi_write_command(chip, 0x74, 1, ¶m); 72 } 73 74 void xonar_hdmi_resume(struct oxygen *chip, struct xonar_hdmi *hdmi) 75 { 76 xonar_hdmi_init_commands(chip, hdmi); 77 } 78 79 void xonar_hdmi_pcm_hardware_filter(unsigned int channel, 80 struct snd_pcm_hardware *hardware) 81 { 82 if (channel == PCM_MULTICH) { 83 hardware->rates = SNDRV_PCM_RATE_44100 | 84 SNDRV_PCM_RATE_48000 | 85 SNDRV_PCM_RATE_96000 | 86 SNDRV_PCM_RATE_192000; 87 hardware->rate_min = 44100; 88 } 89 } 90 91 void xonar_set_hdmi_params(struct oxygen *chip, struct xonar_hdmi *hdmi, 92 struct snd_pcm_hw_params *params) 93 { 94 hdmi->params[0] = 0; /* 1 = non-audio */ 95 switch (params_rate(params)) { 96 case 44100: 97 hdmi->params[1] = IEC958_AES3_CON_FS_44100; 98 break; 99 case 48000: 100 hdmi->params[1] = IEC958_AES3_CON_FS_48000; 101 break; 102 default: /* 96000 */ 103 hdmi->params[1] = IEC958_AES3_CON_FS_96000; 104 break; 105 case 192000: 106 hdmi->params[1] = IEC958_AES3_CON_FS_192000; 107 break; 108 } 109 hdmi->params[2] = params_channels(params) / 2 - 1; 110 if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) 111 hdmi->params[3] = 0; 112 else 113 hdmi->params[3] = 0xc0; 114 hdmi->params[4] = 1; /* ? */ 115 hdmi_write_command(chip, 0x54, 5, hdmi->params); 116 } 117 118 void xonar_hdmi_uart_input(struct oxygen *chip) 119 { 120 if (chip->uart_input_count >= 2 && 121 chip->uart_input[chip->uart_input_count - 2] == 'O' && 122 chip->uart_input[chip->uart_input_count - 1] == 'K') { 123 dev_dbg(chip->card->dev, "message from HDMI chip received:\n"); 124 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, 125 chip->uart_input, chip->uart_input_count); 126 chip->uart_input_count = 0; 127 } 128 } 129