^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for Digigram VX soundcards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * IEC958 stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sound/vx_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "vx_cmd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * vx_modify_board_clock - tell the board that its clock has been modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @sync: DSP needs to resynchronize its FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int vx_modify_board_clock(struct vx_core *chip, int sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct vx_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) vx_init_rmh(&rmh, CMD_MODIFY_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Ask the DSP to resynchronize its FIFO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) rmh.Cmd[0] |= CMD_MODIFY_CLOCK_S_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return vx_send_msg(chip, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * vx_modify_board_inputs - resync audio inputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int vx_modify_board_inputs(struct vx_core *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct vx_rmh rmh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) vx_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) rmh.Cmd[0] |= 1 << 0; /* reference: AUDIO 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return vx_send_msg(chip, &rmh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * vx_read_one_cbit - read one bit from UER config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * @index: the bit index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * returns 0 or 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int vx_read_one_cbit(struct vx_core *chip, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (chip->type >= VX_TYPE_VXPOCKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) vx_outb(chip, CSUER, 1); /* read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) vx_outb(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) val = (vx_inb(chip, RUER) >> 7) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) vx_outl(chip, CSUER, 1); /* read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) vx_outl(chip, RUER, index & XX_UER_CBITS_OFFSET_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) val = (vx_inl(chip, RUER) >> 7) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * vx_write_one_cbit - write one bit to UER config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @index: the bit index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @val: bit value, 0 or 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) val = !!val; /* 0 or 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (vx_is_pcmcia(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) vx_outb(chip, CSUER, 0); /* write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) vx_outb(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) vx_outl(chip, CSUER, 0); /* write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) vx_outl(chip, RUER, (val << 7) | (index & XX_UER_CBITS_OFFSET_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * vx_read_uer_status - read the current UER status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @mode: pointer to store the UER mode, VX_UER_MODE_XXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * returns the frequency of UER, or 0 if not sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int vx_read_uer_status(struct vx_core *chip, unsigned int *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int val, freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Default values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) freq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Read UER status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (vx_is_pcmcia(chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) val = vx_inb(chip, CSUER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) val = vx_inl(chip, CSUER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* If clock is present, read frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (val & VX_SUER_CLOCK_PRESENT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) switch (val & VX_SUER_FREQ_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case VX_SUER_FREQ_32KHz_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) freq = 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case VX_SUER_FREQ_44KHz_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) freq = 44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case VX_SUER_FREQ_48KHz_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) freq = 48000;
^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) if (val & VX_SUER_DATA_PRESENT_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* bit 0 corresponds to consumer/professional bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *mode = vx_read_one_cbit(chip, 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) VX_UER_MODE_PROFESSIONAL : VX_UER_MODE_CONSUMER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *mode = VX_UER_MODE_NOT_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * compute the sample clock value from frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * The formula is as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * HexFreq = (dword) ((double) ((double) 28224000 / (double) Frequency))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * switch ( HexFreq & 0x00000F00 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * case 0x00000100: ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * case 0x00000200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * case 0x00000300: HexFreq -= 0x00000201 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * case 0x00000400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * case 0x00000500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * case 0x00000600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * case 0x00000700: HexFreq = (dword) (((double) 28224000 / (double) (Frequency*2)) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * default : HexFreq = (dword) ((double) 28224000 / (double) (Frequency*4)) - 0x000001FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int hexfreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (snd_BUG_ON(freq <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) hexfreq = (28224000 * 10) / freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) hexfreq = (hexfreq + 5) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* max freq = 55125 Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (snd_BUG_ON(hexfreq <= 0x00000200))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (hexfreq <= 0x03ff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return hexfreq - 0x00000201;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (hexfreq <= 0x07ff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return (hexfreq / 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (hexfreq <= 0x0fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return (hexfreq / 4) + 0x000001ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0x5fe; /* min freq = 6893 Hz */
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * vx_change_clock_source - change the clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * @source: the new source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void vx_change_clock_source(struct vx_core *chip, int source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* we mute DAC to prevent clicks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) vx_toggle_dac_mute(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) chip->ops->set_clock_source(chip, source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) chip->clock_source = source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* unmute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) vx_toggle_dac_mute(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * set the internal clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* Get real clock value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) clock = vx_calc_clock_from_freq(chip, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) snd_printdd(KERN_DEBUG "set internal clock to 0x%x from freq %d\n", clock, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (vx_is_pcmcia(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) vx_outb(chip, HIFREQ, (clock >> 8) & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) vx_outb(chip, LOFREQ, clock & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) vx_outl(chip, HIFREQ, (clock >> 8) & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) vx_outl(chip, LOFREQ, clock & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * set the iec958 status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * @bits: 32-bit status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) void vx_set_iec958_status(struct vx_core *chip, unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (chip->chip_status & VX_STAT_IS_STALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) for (i = 0; i < 32; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) vx_write_one_cbit(chip, i, bits & (1 << i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * vx_set_clock - change the clock and audio source if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int vx_set_clock(struct vx_core *chip, unsigned int freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int src_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (chip->chip_status & VX_STAT_IS_STALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* change the audio source if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) vx_sync_audio_source(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (chip->clock_mode == VX_CLOCK_MODE_EXTERNAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) chip->audio_source == VX_AUDIO_SRC_DIGITAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (chip->clock_source != UER_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) vx_change_clock_source(chip, UER_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mdelay(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) src_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) } else if (chip->clock_mode == VX_CLOCK_MODE_INTERNAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (chip->clock_mode == VX_CLOCK_MODE_AUTO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) chip->audio_source != VX_AUDIO_SRC_DIGITAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (chip->clock_source != INTERNAL_QUARTZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) vx_change_clock_source(chip, INTERNAL_QUARTZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) src_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (chip->freq == freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) vx_set_internal_clock(chip, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (src_changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) vx_modify_board_inputs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (chip->freq == freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) chip->freq = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) vx_modify_board_clock(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^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) * vx_change_frequency - called from interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int vx_change_frequency(struct vx_core *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (chip->chip_status & VX_STAT_IS_STALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (chip->clock_source == INTERNAL_QUARTZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * Read the real UER board frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) freq = vx_read_uer_status(chip, &chip->uer_detected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (freq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * The frequency computed by the DSP is good and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * is different from the previous computed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (freq == 48000 || freq == 44100 || freq == 32000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) chip->freq_detected = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }