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-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) }