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) /* -*- linux-c -*- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * ALSA driver for the digigram lx6464es interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2008, 2009 Tim Blechmann <tim@klingt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/pci.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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "lx6464es.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) MODULE_AUTHOR("Tim Blechmann");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) MODULE_DESCRIPTION("digigram lx6464es");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) MODULE_PARM_DESC(index, "Index value for Digigram LX6464ES interface.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) MODULE_PARM_DESC(id, "ID string for  Digigram LX6464ES interface.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) MODULE_PARM_DESC(enable, "Enable/disable specific Digigram LX6464ES soundcards.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) static const char card_name[] = "LX6464ES";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define PCI_DEVICE_ID_PLX_LX6464ES		PCI_DEVICE_ID_PLX_9056
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) static const struct pci_device_id snd_lx6464es_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 			 PCI_VENDOR_ID_DIGIGRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 			 PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	},			/* LX6464ES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 			 PCI_VENDOR_ID_DIGIGRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 			 PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	},			/* LX6464ES-CAE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 			 PCI_VENDOR_ID_DIGIGRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 			 PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ESE_SERIAL_SUBSYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	},			/* LX6464ESe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 			 PCI_VENDOR_ID_DIGIGRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 			 PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ESE_CAE_SERIAL_SUBSYSTEM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	},			/* LX6464ESe-CAE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	{ 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids);
^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) /* PGO pour USERo dans le registre pci_0x06/loc_0xEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define CHIPSC_RESET_XILINX (1L<<16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /* alsa callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static const struct snd_pcm_hardware lx_caps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	.info             = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 			     SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 			     SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 			     SNDRV_PCM_INFO_SYNC_START),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	.formats	  = (SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 			     SNDRV_PCM_FMTBIT_S16_BE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 			     SNDRV_PCM_FMTBIT_S24_3LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 			     SNDRV_PCM_FMTBIT_S24_3BE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	.rates            = (SNDRV_PCM_RATE_CONTINUOUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 			     SNDRV_PCM_RATE_8000_192000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	.rate_min         = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	.rate_max         = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	.channels_min     = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	.channels_max     = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	.buffer_bytes_max = 64*2*3*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	.period_bytes_min = (2*2*MICROBLAZE_IBL_MIN*2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	.period_bytes_max = (4*64*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	.periods_min      = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	.periods_max      = MAX_STREAM_BUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static int lx_set_granularity(struct lx6464es *chip, u32 gran);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static int lx_hardware_open(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 			    struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	int channels = runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	snd_pcm_uframes_t period_size = runtime->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	dev_dbg(chip->card->dev, "allocating pipe for %d channels\n", channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	err = lx_pipe_allocate(chip, 0, is_capture, channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		dev_err(chip->card->dev, LXP "allocating pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	err = lx_set_granularity(chip, period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		dev_err(chip->card->dev, "setting granularity to %ld failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 			   period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) static int lx_hardware_start(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			     struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	dev_dbg(chip->card->dev, "setting stream format\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	err = lx_stream_set_format(chip, runtime, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 		dev_err(chip->card->dev, "setting stream format failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		return err;
^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) 	dev_dbg(chip->card->dev, "starting pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	err = lx_pipe_start(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		dev_err(chip->card->dev, "starting pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	dev_dbg(chip->card->dev, "waiting for pipe to start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	err = lx_pipe_wait_for_start(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		dev_err(chip->card->dev, "waiting for pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static int lx_hardware_stop(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			    struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	dev_dbg(chip->card->dev, "pausing pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	err = lx_pipe_pause(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		dev_err(chip->card->dev, "pausing pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	dev_dbg(chip->card->dev, "waiting for pipe to become idle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	err = lx_pipe_wait_for_idle(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		dev_err(chip->card->dev, "waiting for pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	dev_dbg(chip->card->dev, "stopping pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	err = lx_pipe_stop(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		dev_err(chip->card->dev, "stopping pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) static int lx_hardware_close(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 			     struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	dev_dbg(chip->card->dev, "releasing pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	err = lx_pipe_release(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		dev_err(chip->card->dev, "releasing pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) static int lx_pcm_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	int board_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	dev_dbg(chip->card->dev, "->lx_pcm_open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	mutex_lock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	/* copy the struct snd_pcm_hardware struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	runtime->hw = lx_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	/* buffer-size should better be multiple of period-size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 					    SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		dev_warn(chip->card->dev, "could not constrain periods\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	/* the clock rate cannot be changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	board_rate = chip->board_sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	err = snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 					   board_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		dev_warn(chip->card->dev, "could not constrain periods\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	/* constrain period size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	err = snd_pcm_hw_constraint_minmax(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 					   MICROBLAZE_IBL_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 					   MICROBLAZE_IBL_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		dev_warn(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			   "could not constrain period size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	snd_pcm_hw_constraint_step(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 				   SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	snd_pcm_set_sync(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	runtime->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	mutex_unlock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	dev_dbg(chip->card->dev, "<-lx_pcm_open, %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) static int lx_pcm_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	dev_dbg(substream->pcm->card->dev, "->lx_pcm_close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 					       *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	snd_pcm_uframes_t pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	struct lx_stream *lx_stream = is_capture ? &chip->capture_stream :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		&chip->playback_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	dev_dbg(chip->card->dev, "->lx_pcm_stream_pointer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	pos = lx_stream->frame_pos * substream->runtime->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	dev_dbg(chip->card->dev, "stream_pointer at %ld\n", pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static int lx_pcm_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	dev_dbg(chip->card->dev, "->lx_pcm_prepare\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	mutex_lock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	if (chip->hardware_running[is_capture]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		err = lx_hardware_stop(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 			dev_err(chip->card->dev, "failed to stop hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 				   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		err = lx_hardware_close(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 			dev_err(chip->card->dev, "failed to close hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 				   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	dev_dbg(chip->card->dev, "opening hardware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	err = lx_hardware_open(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		dev_err(chip->card->dev, "failed to open hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 			   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	err = lx_hardware_start(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		dev_err(chip->card->dev, "failed to start hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	chip->hardware_running[is_capture] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	if (chip->board_sample_rate != substream->runtime->rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			chip->board_sample_rate = substream->runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	mutex_unlock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) static int lx_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 			    struct snd_pcm_hw_params *hw_params, int is_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	dev_dbg(chip->card->dev, "->lx_pcm_hw_params\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	mutex_lock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (is_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		chip->capture_stream.stream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		chip->playback_stream.stream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	mutex_unlock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) static int lx_pcm_hw_params_playback(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 				 struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	return lx_pcm_hw_params(substream, hw_params, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) static int lx_pcm_hw_params_capture(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 				 struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	return lx_pcm_hw_params(substream, hw_params, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) static int lx_pcm_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	dev_dbg(chip->card->dev, "->lx_pcm_hw_free\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	mutex_lock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	if (chip->hardware_running[is_capture]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		err = lx_hardware_stop(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 			dev_err(chip->card->dev, "failed to stop hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 				   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		err = lx_hardware_close(chip, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 			dev_err(chip->card->dev, "failed to close hardware. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				   "Error code %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		chip->hardware_running[is_capture] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	if (is_capture)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		chip->capture_stream.stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		chip->playback_stream.stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	mutex_unlock(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	struct snd_pcm_substream *substream = lx_stream->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	const unsigned int is_capture = lx_stream->is_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	const u32 channels = substream->runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	const u32 bytes_per_frame = channels * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	const u32 period_size = substream->runtime->period_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	const u32 periods = substream->runtime->periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	const u32 period_bytes = period_size * bytes_per_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	dma_addr_t buf = substream->dma_buffer.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	u32 needed, freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	u32 size_array[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	for (i = 0; i != periods; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		u32 buffer_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				    size_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		dev_dbg(chip->card->dev, "starting: needed %d, freed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 			    needed, freed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		err = lx_buffer_give(chip, 0, is_capture, period_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 				     lower_32_bits(buf), upper_32_bits(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 				     &buffer_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		dev_dbg(chip->card->dev, "starting: buffer index %x on 0x%lx (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			    buffer_index, (unsigned long)buf, period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		buf += period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	dev_dbg(chip->card->dev, "starting: needed %d, freed %d\n", needed, freed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	dev_dbg(chip->card->dev, "starting: starting stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	err = lx_stream_start(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		dev_err(chip->card->dev, "couldn't start stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		lx_stream->status = LX_STREAM_STATUS_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	lx_stream->frame_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	const unsigned int is_capture = lx_stream->is_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	dev_dbg(chip->card->dev, "stopping: stopping stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	err = lx_stream_stop(chip, 0, is_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		dev_err(chip->card->dev, "couldn't stop stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		lx_stream->status = LX_STREAM_STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) static void lx_trigger_dispatch_stream(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 				       struct lx_stream *lx_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	switch (lx_stream->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	case LX_STREAM_STATUS_SCHEDULE_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		lx_trigger_start(chip, lx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	case LX_STREAM_STATUS_SCHEDULE_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		lx_trigger_stop(chip, lx_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) static int lx_pcm_trigger_dispatch(struct lx6464es *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 				   struct lx_stream *lx_stream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		lx_stream->status = LX_STREAM_STATUS_SCHEDULE_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	lx_trigger_dispatch_stream(chip, &chip->capture_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	lx_trigger_dispatch_stream(chip, &chip->playback_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) static int lx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	struct lx6464es *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	struct lx_stream *stream = is_capture ? &chip->capture_stream :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		&chip->playback_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	dev_dbg(chip->card->dev, "->lx_pcm_trigger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	return lx_pcm_trigger_dispatch(chip, stream, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static int snd_lx6464es_free(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	dev_dbg(chip->card->dev, "->snd_lx6464es_free\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	lx_irq_disable(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	iounmap(chip->port_dsp_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	ioport_unmap(chip->port_plx_remapped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	pci_release_regions(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) static int snd_lx6464es_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	return snd_lx6464es_free(device->device_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) /* reset the dsp during initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static int lx_init_xilinx_reset(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	dev_dbg(chip->card->dev, "->lx_init_xilinx_reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	/* activate reset of xilinx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	plx_reg &= ~CHIPSC_RESET_XILINX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	lx_plx_reg_write(chip, ePLX_MBOX3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	plx_reg |= CHIPSC_RESET_XILINX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	/* deactivate reset of xilinx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	for (i = 0; i != 100; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		u32 reg_mbox3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		if (reg_mbox3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 			dev_dbg(chip->card->dev, "xilinx reset done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 			dev_dbg(chip->card->dev, "xilinx took %d loops\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	/* todo: add some error handling? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	/* clear mr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	lx_dsp_reg_write(chip, eReg_CSM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	/* le xilinx ES peut ne pas etre encore pret, on attend. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	msleep(600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) static int lx_init_xilinx_test(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	dev_dbg(chip->card->dev, "->lx_init_xilinx_test\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	/* TEST if we have access to Xilinx/MicroBlaze */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	lx_dsp_reg_write(chip, eReg_CSM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	reg = lx_dsp_reg_read(chip, eReg_CSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		dev_err(chip->card->dev, "Problem: Reg_CSM %x.\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		/* PCI9056_SPACE0_REMAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		lx_plx_reg_write(chip, ePLX_PCICR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		reg = lx_dsp_reg_read(chip, eReg_CSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		if (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 			dev_err(chip->card->dev, "Error: Reg_CSM %x.\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			return -EAGAIN; /* seems to be appropriate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	dev_dbg(chip->card->dev, "Xilinx/MicroBlaze access test successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) /* initialize ethersound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) static int lx_init_ethersound_config(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	/* configure 64 io channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		(64 << IOCR_INPUTS_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		(64 << IOCR_OUTPUTS_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		(FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	dev_dbg(chip->card->dev, "->lx_init_ethersound\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	chip->freq_ratio = FREQ_RATIO_SINGLE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	 * write it to the card !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	 * this actually kicks the ES xilinx, the first time since poweron.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	 * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	 * is not ready before this is done, and the bit 2 in Reg_CSES is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	 * */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	lx_dsp_reg_write(chip, eReg_CONFES, conf_es);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	for (i = 0; i != 1000; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		if (lx_dsp_reg_read(chip, eReg_CSES) & 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			dev_dbg(chip->card->dev, "ethersound initialized after %dms\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				   i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			goto ethersound_initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	dev_warn(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		   "ethersound could not be initialized after %dms\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  ethersound_initialized:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	dev_dbg(chip->card->dev, "ethersound initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) static int lx_init_get_version_features(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	u32 dsp_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	dev_dbg(chip->card->dev, "->lx_init_get_version_features\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	err = lx_dsp_get_version(chip, &dsp_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		dev_info(chip->card->dev, "DSP version: V%02d.%02d #%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			   (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			   dsp_version & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		/* later: what firmware version do we expect? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		/* retrieve Play/Rec features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		/* done here because we may have to handle alternate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		 * DSP files. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		/* later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		/* init the EtherSound sample rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		err = lx_dsp_get_clock_frequency(chip, &freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			chip->board_sample_rate = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		dev_dbg(chip->card->dev, "actual clock frequency %d\n", freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		dev_err(chip->card->dev, "DSP corrupted \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static int lx_set_granularity(struct lx6464es *chip, u32 gran)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	u32 snapped_gran = MICROBLAZE_IBL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	dev_dbg(chip->card->dev, "->lx_set_granularity\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	/* blocksize is a power of 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	while ((snapped_gran < gran) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	       (snapped_gran < MICROBLAZE_IBL_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		snapped_gran *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	if (snapped_gran == chip->pcm_granularity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	err = lx_dsp_set_granularity(chip, snapped_gran);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		dev_warn(chip->card->dev, "could not set granularity\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		err = -EAGAIN;
^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) 	if (snapped_gran != gran)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		dev_err(chip->card->dev, "snapped blocksize to %d\n", snapped_gran);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	dev_dbg(chip->card->dev, "set blocksize on board %d\n", snapped_gran);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	chip->pcm_granularity = snapped_gran;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) /* initialize and test the xilinx dsp chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) static int lx_init_dsp(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	dev_dbg(chip->card->dev, "->lx_init_dsp\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	dev_dbg(chip->card->dev, "initialize board\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	err = lx_init_xilinx_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	dev_dbg(chip->card->dev, "testing board\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	err = lx_init_xilinx_test(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	dev_dbg(chip->card->dev, "initialize ethersound configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	err = lx_init_ethersound_config(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	lx_irq_enable(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	/** \todo the mac address should be ready by not, but it isn't,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	 *  so we wait for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	for (i = 0; i != 1000; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		err = lx_dsp_get_mac(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		    chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			goto mac_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) mac_ready:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	dev_dbg(chip->card->dev, "mac address ready read after: %dms\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	dev_info(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		 "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		   chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		   chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	err = lx_init_get_version_features(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	lx_set_granularity(chip, MICROBLAZE_IBL_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	chip->playback_mute = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) static const struct snd_pcm_ops lx_ops_playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	.open      = lx_pcm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	.close     = lx_pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	.prepare   = lx_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	.hw_params = lx_pcm_hw_params_playback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	.hw_free   = lx_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	.trigger   = lx_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	.pointer   = lx_pcm_stream_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) static const struct snd_pcm_ops lx_ops_capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	.open      = lx_pcm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	.close     = lx_pcm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	.prepare   = lx_pcm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	.hw_params = lx_pcm_hw_params_capture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	.hw_free   = lx_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	.trigger   = lx_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	.pointer   = lx_pcm_stream_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) static int lx_pcm_create(struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	u32 size = 64 *		     /* channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		3 *		     /* 24 bit samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		MAX_STREAM_BUFFER *  /* periods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		MICROBLAZE_IBL_MAX * /* frames per period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		2;		     /* duplex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	size = PAGE_ALIGN(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	/* hardcoded device name & channel count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	err = snd_pcm_new(chip->card, (char *)card_name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			  1, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &lx_ops_playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	pcm->nonatomic = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	strcpy(pcm->name, card_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 				       &chip->pci->dev, size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	chip->capture_stream.is_capture = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static int lx_control_playback_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				    struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) static int lx_control_playback_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 				   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	ucontrol->value.integer.value[0] = chip->playback_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) static int lx_control_playback_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 				   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	struct lx6464es *chip = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	int current_value = chip->playback_mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	if (current_value != ucontrol->value.integer.value[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		lx_level_unmute(chip, 0, !current_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		chip->playback_mute = !current_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) static const struct snd_kcontrol_new lx_control_playback_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	.name = "PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	.index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	.private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	.info = lx_control_playback_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	.get = lx_control_playback_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	.put = lx_control_playback_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) static void lx_proc_levels_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	u32 levels[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	struct lx6464es *chip = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	snd_iprintf(buffer, "capture levels:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	err = lx_level_peaks(chip, 1, 64, levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	for (i = 0; i != 8; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		for (j = 0; j != 8; ++j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 			snd_iprintf(buffer, "%08x ", levels[i*8+j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	snd_iprintf(buffer, "\nplayback levels:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	err = lx_level_peaks(chip, 0, 64, levels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	for (i = 0; i != 8; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		for (j = 0; j != 8; ++j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			snd_iprintf(buffer, "%08x ", levels[i*8+j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static int lx_proc_create(struct snd_card *card, struct lx6464es *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	return snd_card_ro_proc_new(card, "levels", chip, lx_proc_levels_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) static int snd_lx6464es_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			       struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			       struct lx6464es **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	struct lx6464es *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		.dev_free = snd_lx6464es_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	dev_dbg(card->dev, "->snd_lx6464es_create\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	*rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* enable PCI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	err = pci_enable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	/* check if we can restrict PCI DMA transfers to 32 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	err = dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		dev_err(card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			"architecture does not support 32bit PCI busmaster DMA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		goto alloc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	/* initialize synchronization structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	mutex_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	mutex_init(&chip->msg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	mutex_init(&chip->setup_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	/* request resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	err = pci_request_regions(pci, card_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		goto request_regions_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	/* plx port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	chip->port_plx = pci_resource_start(pci, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	chip->port_plx_remapped = ioport_map(chip->port_plx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 					     pci_resource_len(pci, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	/* dsp port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (!chip->port_dsp_bar) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		dev_err(card->dev, "cannot remap PCI memory region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		goto remap_pci_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	err = request_threaded_irq(pci->irq, lx_interrupt, lx_threaded_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 				   IRQF_SHARED, KBUILD_MODNAME, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		goto request_irq_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		goto device_new_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	err = lx_init_dsp(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		dev_err(card->dev, "error during DSP initialization\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	err = lx_pcm_create(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	err = lx_proc_create(card, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	err = snd_ctl_add(card, snd_ctl_new1(&lx_control_playback_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 					     chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	*rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) device_new_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	free_irq(pci->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) request_irq_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	iounmap(chip->port_dsp_bar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) remap_pci_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	pci_release_regions(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) request_regions_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) alloc_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static int snd_lx6464es_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			      const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	struct lx6464es *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	dev_dbg(&pci->dev, "->snd_lx6464es_probe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			   0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	err = snd_lx6464es_create(card, pci, &chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		dev_err(card->dev, "error during snd_lx6464es_create\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	strcpy(card->driver, "LX6464ES");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	sprintf(card->id, "LX6464ES_%02X%02X%02X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		card->shortname, chip->port_plx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		chip->port_dsp_bar, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	dev_dbg(chip->card->dev, "initialization successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static void snd_lx6464es_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static struct pci_driver lx6464es_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	.name =     KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	.id_table = snd_lx6464es_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	.probe =    snd_lx6464es_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	.remove = snd_lx6464es_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) module_pci_driver(lx6464es_driver);