cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xonar_hdmi.c (2999B)


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