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)  * Driver for AT73C213 16-bit stereo DAC connected to Atmel SSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2006-2007 Atmel Norway
^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) /*#define DEBUG*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/atmel-ssc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/spi/at73c213.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include "at73c213.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define BITRATE_MIN	 8000 /* Hardware limit? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define BITRATE_TARGET	CONFIG_SND_AT73C213_TARGET_BITRATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define BITRATE_MAX	50000 /* Hardware limit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) /* Initial (hardware reset) AT73C213 register values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) static const u8 snd_at73c213_original_image[18] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	0x00,	/* 00 - CTRL    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	0x05,	/* 01 - LLIG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	0x05,	/* 02 - RLIG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	0x08,	/* 03 - LPMG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	0x08,	/* 04 - RPMG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	0x00,	/* 05 - LLOG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	0x00,	/* 06 - RLOG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	0x22,	/* 07 - OLC     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	0x09,	/* 08 - MC      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	0x00,	/* 09 - CSFC    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	0x00,	/* 0A - MISC    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	0x00,	/* 0B -         */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	0x00,	/* 0C - PRECH   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	0x05,	/* 0D - AUXG    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	0x00,	/* 0E -         */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	0x00,	/* 0F -         */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	0x00,	/* 10 - RST     */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	0x00,	/* 11 - PA_CTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) struct snd_at73c213 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	struct snd_card			*card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	struct snd_pcm			*pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct snd_pcm_substream	*substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct at73c213_board_info	*board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	int				irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	int				period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	unsigned long			bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	struct ssc_device		*ssc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	struct spi_device		*spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	u8				spi_wbuffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	u8				spi_rbuffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	/* Image of the SPI registers in AT73C213. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	u8				reg_image[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	/* Protect SSC registers against concurrent access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	spinlock_t			lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	/* Protect mixer registers against concurrent access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	struct mutex			mixer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define get_chip(card) ((struct snd_at73c213 *)card->private_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) snd_at73c213_write_reg(struct snd_at73c213 *chip, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	struct spi_transfer msg_xfer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		.len		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		.cs_change	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	chip->spi_wbuffer[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	chip->spi_wbuffer[1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	msg_xfer.tx_buf = chip->spi_wbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	msg_xfer.rx_buf = chip->spi_rbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	spi_message_add_tail(&msg_xfer, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	retval = spi_sync(chip->spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		chip->reg_image[reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) static struct snd_pcm_hardware snd_at73c213_playback_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	.info		= SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 			  SNDRV_PCM_INFO_BLOCK_TRANSFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	.formats	= SNDRV_PCM_FMTBIT_S16_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	.rates		= SNDRV_PCM_RATE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	.rate_min	= 8000,  /* Replaced by chip->bitrate later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	.rate_max	= 50000, /* Replaced by chip->bitrate later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	.channels_min	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	.channels_max	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	.buffer_bytes_max = 64 * 1024 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	.period_bytes_min = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	.period_bytes_max = 64 * 1024 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	.periods_min	= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	.periods_max	= 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  * Calculate and set bitrate and divisions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	unsigned long ssc_rate = clk_get_rate(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	unsigned long dac_rate_new, ssc_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	unsigned long ssc_div_max, ssc_div_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	int max_tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	 * We connect two clocks here, picking divisors so the I2S clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	 * out data at the same rate the DAC clocks it in ... and as close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	 * as practical to the desired target rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	 * The DAC master clock (MCLK) is programmable, and is either 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	 * or (not here) 384 times the I2S output clock (BCLK).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	/* SSC clock / (bitrate * stereo * 16-bit). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	ssc_div = ssc_rate / (BITRATE_TARGET * 2 * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	ssc_div_min = ssc_rate / (BITRATE_MAX * 2 * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	ssc_div_max = ssc_rate / (BITRATE_MIN * 2 * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	max_tries = (ssc_div_max - ssc_div_min) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	if (max_tries < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		max_tries = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	/* ssc_div must be even. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	ssc_div = (ssc_div + 1) & ~1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		ssc_div -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		if ((ssc_rate / (ssc_div * 2 * 16)) > BITRATE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	/* Search for a possible bitrate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		/* SSC clock / (ssc divider * 16-bit * stereo). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		/* 256 / (2 * 16) = 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		dac_rate_new = 8 * (ssc_rate / ssc_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		status = clk_round_rate(chip->board->dac_clk, dac_rate_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		if (status <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		/* Ignore difference smaller than 256 Hz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		if ((status/256) == (dac_rate_new/256))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			goto set_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		ssc_div += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	} while (--max_tries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	/* Not able to find a valid bitrate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) set_rate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	status = clk_set_rate(chip->board->dac_clk, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	/* Set divider in SSC device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	ssc_writel(chip->ssc->regs, CMR, ssc_div/2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	/* SSC clock / (ssc divider * 16-bit * stereo). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	chip->bitrate = ssc_rate / (ssc_div * 16 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	dev_info(&chip->spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			"at73c213: supported bitrate is %lu (%lu divider)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 			chip->bitrate, ssc_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) static int snd_at73c213_pcm_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	/* ensure buffer_size is a multiple of period_size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 					SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	snd_at73c213_playback_hw.rate_min = chip->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	snd_at73c213_playback_hw.rate_max = chip->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	runtime->hw = snd_at73c213_playback_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	chip->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	err = clk_enable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	return 0;
^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) static int snd_at73c213_pcm_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	chip->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	clk_disable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static int snd_at73c213_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 				 struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	int channels = params_channels(hw_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	val = ssc_readl(chip->ssc->regs, TFMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	val = SSC_BFINS(TFMR_DATNB, channels - 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	ssc_writel(chip->ssc->regs, TFMR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) static int snd_at73c213_pcm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	block_size = frames_to_bytes(runtime, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	chip->period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	ssc_writel(chip->ssc->regs, PDC_TPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			(long)runtime->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	ssc_writel(chip->ssc->regs, PDC_TCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 			runtime->period_size * runtime->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	ssc_writel(chip->ssc->regs, PDC_TNPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			(long)runtime->dma_addr + block_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	ssc_writel(chip->ssc->regs, PDC_TNCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			runtime->period_size * runtime->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static int snd_at73c213_pcm_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				   int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		ssc_writel(chip->ssc->regs, IER, SSC_BIT(IER_ENDTX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTDIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		ssc_writel(chip->ssc->regs, IDR, SSC_BIT(IDR_ENDTX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) snd_at73c213_pcm_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	snd_pcm_uframes_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	unsigned long bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	bytes = ssc_readl(chip->ssc->regs, PDC_TPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		- (unsigned long)runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	pos = bytes_to_frames(runtime, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	if (pos >= runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		pos -= runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static const struct snd_pcm_ops at73c213_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	.open		= snd_at73c213_pcm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	.close		= snd_at73c213_pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	.hw_params	= snd_at73c213_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	.prepare	= snd_at73c213_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	.trigger	= snd_at73c213_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	.pointer	= snd_at73c213_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) static int snd_at73c213_pcm_new(struct snd_at73c213 *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	retval = snd_pcm_new(chip->card, chip->card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			device, 1, 0, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	strcpy(pcm->name, "at73c213");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &at73c213_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	snd_pcm_set_managed_buffer_all(chip->pcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 			SNDRV_DMA_TYPE_DEV, &chip->ssc->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			64 * 1024, 64 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) static irqreturn_t snd_at73c213_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	struct snd_at73c213 *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	struct snd_pcm_runtime *runtime = chip->substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	int block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	int next_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	int retval = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	block_size = frames_to_bytes(runtime, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	status = ssc_readl(chip->ssc->regs, IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	if (status & SSC_BIT(IMR_ENDTX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		chip->period++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		if (chip->period == runtime->periods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			chip->period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		next_period = chip->period + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		if (next_period == runtime->periods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			next_period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		offset = block_size * next_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		ssc_writel(chip->ssc->regs, PDC_TNPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 				(long)runtime->dma_addr + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		ssc_writel(chip->ssc->regs, PDC_TNCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 				runtime->period_size * runtime->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		retval = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	ssc_readl(chip->ssc->regs, IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (status & SSC_BIT(IMR_ENDTX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		snd_pcm_period_elapsed(chip->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)  * Mixer functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		(chip->reg_image[reg] >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	int change, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	val = (chip->reg_image[reg] & ~(mask << shift)) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	change = val != chip->reg_image[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	retval = snd_at73c213_write_reg(chip, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) static int snd_at73c213_stereo_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	if (mask == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		(chip->reg_image[left_reg] >> shift_left) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	ucontrol->value.integer.value[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		(chip->reg_image[right_reg] >> shift_right) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		ucontrol->value.integer.value[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			mask - ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	int left_reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	int shift_right = (kcontrol->private_value >> 19) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	int mask = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	int invert = (kcontrol->private_value >> 22) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	int change, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	unsigned short val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	val1 = ucontrol->value.integer.value[0] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	val2 = ucontrol->value.integer.value[1] & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (invert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		val1 = mask - val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		val2 = mask - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	val1 <<= shift_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	val2 <<= shift_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	change = val1 != chip->reg_image[left_reg]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		|| val2 != chip->reg_image[right_reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	retval = snd_at73c213_write_reg(chip, left_reg, val1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	retval = snd_at73c213_write_reg(chip, right_reg, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) #define snd_at73c213_mono_switch_info	snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		(chip->reg_image[reg] >> shift) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			0x01 - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	int reg = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	int invert = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	int change, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		val = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	if (invert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	mutex_lock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	val |= (chip->reg_image[reg] & ~(mask << shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	change = val != chip->reg_image[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	retval = snd_at73c213_write_reg(chip, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	mutex_unlock(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) static int snd_at73c213_pa_volume_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xff) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) static int snd_at73c213_line_capture_volume_info(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	/* When inverted will give values 0x10001 => 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	uinfo->value.integer.min = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	uinfo->value.integer.max = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) static int snd_at73c213_aux_capture_volume_info(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	/* When inverted will give values 0x10001 => 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	uinfo->value.integer.min = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	uinfo->value.integer.max = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) #define AT73C213_MONO_SWITCH(xname, xindex, reg, shift, mask, invert)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	.name = xname,							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	.index = xindex,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	.info = snd_at73c213_mono_switch_info,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	.get = snd_at73c213_mono_switch_get,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	.put = snd_at73c213_mono_switch_put,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	.private_value = (reg | (shift << 8) | (mask << 16) | (invert << 24)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) #define AT73C213_STEREO(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	.name = xname,							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	.index = xindex,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	.info = snd_at73c213_stereo_info,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	.get = snd_at73c213_stereo_get,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	.put = snd_at73c213_stereo_put,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	.private_value = (left_reg | (right_reg << 8)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			| (shift_left << 16) | (shift_right << 19)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			| (mask << 24) | (invert << 22))		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) static const struct snd_kcontrol_new snd_at73c213_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1f, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1f, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) AT73C213_STEREO("PCM Playback Switch", 0, DAC_LLOG, DAC_RLOG, 5, 5, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) AT73C213_MONO_SWITCH("Mono PA Playback Switch", 0, DAC_CTRL, DAC_CTRL_ONPADRV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		     0x01, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	.name	= "PA Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	.index	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	.info	= snd_at73c213_pa_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	.get	= snd_at73c213_mono_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	.put	= snd_at73c213_mono_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	.private_value	= PA_CTRL | (PA_CTRL_APAGAIN << 8) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		(0x0f << 16) | (1 << 24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) AT73C213_MONO_SWITCH("PA High Gain Playback Switch", 0, PA_CTRL, PA_CTRL_APALP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		     0x01, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) AT73C213_MONO_SWITCH("PA Playback Switch", 0, PA_CTRL, PA_CTRL_APAON, 0x01, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	.name	= "Aux Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	.index	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	.info	= snd_at73c213_aux_capture_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	.get	= snd_at73c213_mono_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	.put	= snd_at73c213_mono_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	.private_value	= DAC_AUXG | (0 << 8) | (0x1f << 16) | (1 << 24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) AT73C213_MONO_SWITCH("Aux Capture Switch", 0, DAC_CTRL, DAC_CTRL_ONAUXIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		     0x01, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	.name	= "Line Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	.index	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	.info	= snd_at73c213_line_capture_volume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	.get	= snd_at73c213_stereo_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	.put	= snd_at73c213_stereo_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	.private_value	= DAC_LLIG | (DAC_RLIG << 8) | (0 << 16) | (0 << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		| (0x1f << 24) | (1 << 22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) static int snd_at73c213_mixer(struct snd_at73c213 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	int errval, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	if (chip == NULL || chip->pcm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	card = chip->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	strcpy(card->mixername, chip->pcm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	for (idx = 0; idx < ARRAY_SIZE(snd_at73c213_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		errval = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 				snd_ctl_new1(&snd_at73c213_controls[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 					chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		if (errval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	for (idx = 1; idx < ARRAY_SIZE(snd_at73c213_controls) + 1; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		kctl = snd_ctl_find_numid(card, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		if (kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			snd_ctl_remove(card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	return errval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739)  * Device functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) static int snd_at73c213_ssc_init(struct snd_at73c213 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	 * Continuous clock output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	 * Starts on falling TF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	 * Delay 1 cycle (1 bit).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	 * Periode is 16 bit (16 - 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	ssc_writel(chip->ssc->regs, TCMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			SSC_BF(TCMR_CKO, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			| SSC_BF(TCMR_START, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			| SSC_BF(TCMR_STTDLY, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			| SSC_BF(TCMR_PERIOD, 16 - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	 * Data length is 16 bit (16 - 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	 * Transmit MSB first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	 * Transmit 2 words each transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	 * Frame sync length is 16 bit (16 - 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	 * Frame starts on negative pulse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	ssc_writel(chip->ssc->regs, TFMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			SSC_BF(TFMR_DATLEN, 16 - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			| SSC_BIT(TFMR_MSBF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			| SSC_BF(TFMR_DATNB, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			| SSC_BF(TFMR_FSLEN, 16 - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			| SSC_BF(TFMR_FSOS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) static int snd_at73c213_chip_init(struct snd_at73c213 *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	unsigned char dac_ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	retval = snd_at73c213_set_bitrate(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	/* Enable DAC master clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	retval = clk_enable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	/* Initialize at73c213 on SPI bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	retval = snd_at73c213_write_reg(chip, DAC_RST, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	retval = snd_at73c213_write_reg(chip, DAC_RST, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	/* Precharge everything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	retval = snd_at73c213_write_reg(chip, PA_CTRL, (1<<PA_CTRL_APAPRECH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	retval = snd_at73c213_write_reg(chip, DAC_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			(1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	/* Stop precharging PA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	retval = snd_at73c213_write_reg(chip, PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			(1<<PA_CTRL_APALP) | 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	msleep(450);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	/* Stop precharging DAC, turn on master power. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	retval = snd_at73c213_write_reg(chip, DAC_PRECH, (1<<DAC_PRECH_ONMSTR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	/* Turn on DAC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	dac_ctrl = (1<<DAC_CTRL_ONDACL) | (1<<DAC_CTRL_ONDACR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		| (1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	retval = snd_at73c213_write_reg(chip, DAC_CTRL, dac_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	/* Mute sound. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		goto out_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	/* Enable I2S device, i.e. clock output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) out_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	clk_disable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) static int snd_at73c213_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	struct snd_at73c213 *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if (chip->irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static int snd_at73c213_dev_init(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				 struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		.dev_free	= snd_at73c213_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	struct snd_at73c213 *chip = get_chip(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	int irq, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	irq = chip->ssc->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	mutex_init(&chip->mixer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	retval = clk_enable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	chip->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	memcpy(&chip->reg_image, &snd_at73c213_original_image,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			sizeof(snd_at73c213_original_image));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	retval = snd_at73c213_ssc_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		goto out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	retval = snd_at73c213_chip_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		goto out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	retval = snd_at73c213_pcm_new(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		goto out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		goto out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	retval = snd_at73c213_mixer(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		goto out_snd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) out_snd_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	snd_device_free(card, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) out_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	clk_disable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static int snd_at73c213_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct snd_card			*card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct snd_at73c213		*chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct at73c213_board_info	*board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	int				retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	char				id[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	board = spi->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (!board) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		dev_dbg(&spi->dev, "no platform_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	if (!board->dac_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		dev_dbg(&spi->dev, "no DAC clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	if (IS_ERR(board->dac_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		dev_dbg(&spi->dev, "no DAC clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		return PTR_ERR(board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	/* Allocate "card" using some unused identifiers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	snprintf(id, sizeof id, "at73c213_%d", board->ssc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	retval = snd_card_new(&spi->dev, -1, id, THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			      sizeof(struct snd_at73c213), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	chip->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	chip->board = board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	chip->ssc = ssc_request(board->ssc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	if (IS_ERR(chip->ssc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		dev_dbg(&spi->dev, "could not get ssc%d device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 				board->ssc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		retval = PTR_ERR(chip->ssc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		goto out_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	retval = snd_at73c213_dev_init(card, spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		goto out_ssc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	strcpy(card->driver, "at73c213");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	strcpy(card->shortname, board->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	sprintf(card->longname, "%s on irq %d", card->shortname, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	retval = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		goto out_ssc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	dev_set_drvdata(&spi->dev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) out_ssc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	ssc_free(chip->ssc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) out_card:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static int snd_at73c213_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	struct snd_card *card = dev_get_drvdata(&spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct snd_at73c213 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	/* Stop playback. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	retval = clk_enable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	clk_disable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	/* Mute sound. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	/* Turn off PA. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	retval = snd_at73c213_write_reg(chip, PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 					chip->reg_image[PA_CTRL] | 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	retval = snd_at73c213_write_reg(chip, PA_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 					(1 << PA_CTRL_APALP) | 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	/* Turn off external DAC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	msleep(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	/* Turn off master power. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	/* Stop DAC master clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	clk_disable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	ssc_free(chip->ssc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int snd_at73c213_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	struct snd_at73c213 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	clk_disable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	clk_disable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int snd_at73c213_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	struct snd_at73c213 *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	retval = clk_enable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	retval = clk_enable(chip->ssc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		clk_disable(chip->board->dac_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static SIMPLE_DEV_PM_OPS(at73c213_pm_ops, snd_at73c213_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		snd_at73c213_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) #define AT73C213_PM_OPS (&at73c213_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) #define AT73C213_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static struct spi_driver at73c213_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		.name	= "at73c213",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		.pm	= AT73C213_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	.probe		= snd_at73c213_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	.remove		= snd_at73c213_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) module_spi_driver(at73c213_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) MODULE_LICENSE("GPL");