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)  *  Asihpi soundcard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *  Copyright (c) by AudioScience Inc <support@audioscience.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  The following is not a condition of use, merely a request:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  If you modify this program, particularly if you fix errors, AudioScience Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *  would appreciate it if you grant us the right to use those modifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  for any purpose including commercial applications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include "hpi_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include "hpi_version.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include "hpimsginit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include "hpioctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "hpicmn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <sound/hwdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 			HPI_VER_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #if defined CONFIG_SND_DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * snd_printddd - very verbose debug printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * @format: format string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  * Works like snd_printk() for debugging purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  * Must set snd module debug parameter to 3 to enable at runtime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define snd_printddd(format, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	__snd_printk(3, __FILE__, __LINE__, format, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define snd_printddd(format, args...) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static bool enable_hpi_hwdep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) module_param(enable_hpi_hwdep, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) MODULE_PARM_DESC(enable_hpi_hwdep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 		"ALSA enable HPI hwdep for AudioScience soundcard ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) /* identify driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #ifdef KERNEL_ALSA_BUILD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static char *build_info = "Built using headers from kernel source";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) module_param(build_info, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) MODULE_PARM_DESC(build_info, "Built using headers from kernel source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) static char *build_info = "Built within ALSA source";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) module_param(build_info, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) MODULE_PARM_DESC(build_info, "Built within ALSA source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) /* set to 1 to dump every control from adapter to log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static const int mixer_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define DEFAULT_SAMPLERATE 44100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static int adapter_fs = DEFAULT_SAMPLERATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) /* defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define PERIODS_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define PERIOD_BYTES_MIN  2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define BUFFER_BYTES_MAX (512 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) struct clk_source {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	int source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) struct clk_cache {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	int has_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct clk_source s[MAX_CLOCKSOURCES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) /* Per card data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) struct snd_card_asihpi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	struct hpi_adapter *hpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	/* In low latency mode there is only one stream, a pointer to its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	 * private data is stored here on trigger and cleared on stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	 * The interrupt handler uses it as a parameter when calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	 * snd_card_asihpi_timer_function().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	struct snd_card_asihpi_pcm *llmode_streampriv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	void (*pcm_start)(struct snd_pcm_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	void (*pcm_stop)(struct snd_pcm_substream *substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	u32 h_mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	struct clk_cache cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	u16 can_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	u16 support_grouping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	u16 support_mrx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	u16 update_interval_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	u16 in_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	u16 out_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	u16 in_min_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	u16 out_min_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) /* Per stream data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) struct snd_card_asihpi_pcm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	unsigned int respawn_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	unsigned int hpi_buffer_attached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	unsigned int buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	unsigned int period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	unsigned int bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	unsigned int pcm_buf_dma_ofs;	/* DMA R/W offset in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	unsigned int pcm_buf_elapsed_dma_ofs;	/* DMA R/W offset in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	unsigned int drained_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	u32 h_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	struct hpi_format format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) /* universal stream verbs work with out or in stream handles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /* Functions to allow driver to give a buffer to HPI for busmastering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static u16 hpi_stream_host_buffer_attach(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	u32 h_stream,   /* handle to outstream. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	u32 size_in_bytes, /* size in bytes of bus mastering buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	u32 pci_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	struct hpi_message hm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	struct hpi_response hr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	unsigned int obj = hpi_handle_object(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	if (!h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		return HPI_ERROR_INVALID_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	hpi_init_message_response(&hm, &hr, obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			obj == HPI_OBJ_OSTREAM ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 				HPI_OSTREAM_HOSTBUFFER_ALLOC :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				HPI_ISTREAM_HOSTBUFFER_ALLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	hpi_handle_to_indexes(h_stream, &hm.adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 				&hm.obj_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	hm.u.d.u.buffer.buffer_size = size_in_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	hm.u.d.u.buffer.pci_address = pci_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	hpi_send_recv(&hm, &hr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	return hr.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) static u16 hpi_stream_host_buffer_detach(u32  h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	struct hpi_message hm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	struct hpi_response hr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	unsigned int obj = hpi_handle_object(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	if (!h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		return HPI_ERROR_INVALID_OBJ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	hpi_init_message_response(&hm, &hr,  obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 			obj == HPI_OBJ_OSTREAM ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 				HPI_OSTREAM_HOSTBUFFER_FREE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 				HPI_ISTREAM_HOSTBUFFER_FREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	hpi_handle_to_indexes(h_stream, &hm.adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 				&hm.obj_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	hpi_send_recv(&hm, &hr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	return hr.error;
^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 inline u16 hpi_stream_start(u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		return hpi_outstream_start(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		return hpi_instream_start(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) static inline u16 hpi_stream_stop(u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		return hpi_outstream_stop(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		return hpi_instream_stop(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static inline u16 hpi_stream_get_info_ex(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)     u32 h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)     u16        *pw_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)     u32        *pbuffer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)     u32        *pdata_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226)     u32        *psample_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)     u32        *pauxiliary_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	u16 e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	if (hpi_handle_object(h_stream)  ==  HPI_OBJ_OSTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		e = hpi_outstream_get_info_ex(h_stream, pw_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 					pbuffer_size, pdata_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 					psample_count, pauxiliary_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		e = hpi_instream_get_info_ex(h_stream, pw_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 					pbuffer_size, pdata_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 					psample_count, pauxiliary_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	return e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) static inline u16 hpi_stream_group_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 					u32 h_master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 					u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	if (hpi_handle_object(h_master) ==  HPI_OBJ_OSTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		return hpi_outstream_group_add(h_master, h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		return hpi_instream_group_add(h_master, h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) static inline u16 hpi_stream_group_reset(u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		return hpi_outstream_group_reset(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		return hpi_instream_group_reset(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) static u16 handle_error(u16 err, int line, char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			"in file %s, line %d: HPI error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			filename, line, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) #define hpi_handle_error(x)  handle_error(x, __LINE__, __FILE__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) /***************************** GENERAL PCM ****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) static void print_hwparams(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 				struct snd_pcm_hw_params *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	snd_pcm_debug_name(substream, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	snd_printdd("%s HWPARAMS\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	snd_printdd(" samplerate=%dHz channels=%d format=%d subformat=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		params_rate(p), params_channels(p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		params_format(p), params_subformat(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	snd_printdd(" buffer=%dB period=%dB period_size=%dB periods=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		params_buffer_bytes(p), params_period_bytes(p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		params_period_size(p), params_periods(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	snd_printdd(" buffer_size=%d access=%d data_rate=%dB/s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		params_buffer_size(p), params_access(p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		params_rate(p) * params_channels(p) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		snd_pcm_format_width(params_format(p)) / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) #define INVALID_FORMAT	(__force snd_pcm_format_t)(-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) static const snd_pcm_format_t hpi_to_alsa_formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	INVALID_FORMAT,		/* INVALID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	SNDRV_PCM_FORMAT_U8,	/* HPI_FORMAT_PCM8_UNSIGNED        1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	SNDRV_PCM_FORMAT_S16,	/* HPI_FORMAT_PCM16_SIGNED         2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	INVALID_FORMAT,		/* HPI_FORMAT_MPEG_L1              3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	SNDRV_PCM_FORMAT_MPEG,	/* HPI_FORMAT_MPEG_L2              4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	SNDRV_PCM_FORMAT_MPEG,	/* HPI_FORMAT_MPEG_L3              5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	INVALID_FORMAT,		/* HPI_FORMAT_DOLBY_AC2            6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	INVALID_FORMAT,		/* HPI_FORMAT_DOLBY_AC3            7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN      8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	INVALID_FORMAT,		/* HPI_FORMAT_AA_TAGIT1_HITS       9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	INVALID_FORMAT,		/* HPI_FORMAT_AA_TAGIT1_INSERTS   10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	SNDRV_PCM_FORMAT_S32,	/* HPI_FORMAT_PCM32_SIGNED        11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	INVALID_FORMAT,		/* HPI_FORMAT_RAW_BITSTREAM       12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	INVALID_FORMAT,		/* HPI_FORMAT_AA_TAGIT1_HITS_EX1  13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	SNDRV_PCM_FORMAT_FLOAT,	/* HPI_FORMAT_PCM32_FLOAT         14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	/* ALSA can't handle 3 byte sample size together with power-of-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	 *  constraint on buffer_bytes, so disable this format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	INVALID_FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	/* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 					   u16 *hpi_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	u16 format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	for (format = HPI_FORMAT_PCM8_UNSIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	     format <= HPI_FORMAT_PCM24_SIGNED; format++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		if (hpi_to_alsa_formats[format] == alsa_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			*hpi_format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	snd_printd(KERN_WARNING "failed match for alsa format %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		   alsa_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	*hpi_format = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 					 struct snd_pcm_hardware *pcmhw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	u32 sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	unsigned int rate_min = 200000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	unsigned int rate_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	unsigned int rates = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (asihpi->support_mrx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		rates |= SNDRV_PCM_RATE_CONTINUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		rates |= SNDRV_PCM_RATE_8000_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		rate_min = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		rate_max = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		/* on cards without SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		   valid rates are determined by sampleclock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		err = hpi_mixer_get_control(asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 					  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 					  HPI_CONTROL_SAMPLECLOCK, &h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 			dev_err(&asihpi->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 				"No local sampleclock, err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		for (idx = -1; idx < 100; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			if (idx == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 				if (hpi_sample_clock_get_sample_rate(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 								&sample_rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			} else if (hpi_sample_clock_query_local_rate(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 							idx, &sample_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 			rate_min = min(rate_min, sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 			rate_max = max(rate_max, sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 			switch (sample_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			case 5512:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 				rates |= SNDRV_PCM_RATE_5512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 			case 8000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 				rates |= SNDRV_PCM_RATE_8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 			case 11025:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 				rates |= SNDRV_PCM_RATE_11025;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			case 16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				rates |= SNDRV_PCM_RATE_16000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 				rates |= SNDRV_PCM_RATE_22050;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 			case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 				rates |= SNDRV_PCM_RATE_32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 			case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 				rates |= SNDRV_PCM_RATE_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 			case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 				rates |= SNDRV_PCM_RATE_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			case 64000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 				rates |= SNDRV_PCM_RATE_64000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 				rates |= SNDRV_PCM_RATE_88200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 				rates |= SNDRV_PCM_RATE_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 				rates |= SNDRV_PCM_RATE_176400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 				rates |= SNDRV_PCM_RATE_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			default: /* some other rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				rates |= SNDRV_PCM_RATE_KNOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	pcmhw->rates = rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	pcmhw->rate_min = rate_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	pcmhw->rate_max = rate_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 					 struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	u16 format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	unsigned int bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	print_hwparams(substream, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	hpi_handle_error(hpi_format_create(&dpcm->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			params_channels(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			format, params_rate(params), 0, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		if (hpi_instream_reset(dpcm->h_stream) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		if (hpi_instream_set_format(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			dpcm->h_stream, &dpcm->format) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	dpcm->hpi_buffer_attached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	if (card->can_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		err = hpi_stream_host_buffer_attach(dpcm->h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			params_buffer_bytes(params),  runtime->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			snd_printdd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				"stream_host_buffer_attach success %u %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				params_buffer_bytes(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 				(unsigned long)runtime->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			snd_printd("stream_host_buffer_attach error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 					err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 				&dpcm->hpi_buffer_attached, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	bytes_per_sec = params_rate(params) * params_channels(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	width = snd_pcm_format_width(params_format(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	bytes_per_sec *= width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	bytes_per_sec /= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	if (width < 0 || bytes_per_sec == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	dpcm->bytes_per_sec = bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	dpcm->buffer_bytes = params_buffer_bytes(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	dpcm->period_bytes = params_period_bytes(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (dpcm->hpi_buffer_attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		hpi_stream_host_buffer_detach(dpcm->h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	kfree(dpcm);
^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) static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 					    substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	int expiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	expiry = HZ / 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	expiry = max(expiry, 1); /* don't let it be zero! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	mod_timer(&dpcm->timer, jiffies + expiry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	dpcm->respawn_timer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	dpcm->respawn_timer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	del_timer(&dpcm->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	struct snd_card_asihpi_pcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct snd_card_asihpi *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	WARN_ON(in_interrupt());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	card->llmode_streampriv = dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		HPI_ADAPTER_PROPERTY_IRQ_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		card->update_interval_frames, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	struct snd_card_asihpi *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	card->llmode_streampriv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 					   int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct snd_pcm_substream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	u16 e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	snd_pcm_debug_name(substream, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		snd_printdd("%s trigger start\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 			struct snd_pcm_runtime *runtime = s->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 			struct snd_card_asihpi_pcm *ds = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			if (snd_pcm_substream_chip(s) != card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 			/* don't link Cap and Play */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 			if (substream->stream != s->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 			ds->drained_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 			if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 				/* How do I know how much valid data is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 				* in buffer? Must be at least one period!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 				* Guessing 2 periods, but if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 				* buffer is bigger it may contain even more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 				* data??
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 				*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 				unsigned int preload = ds->period_bytes * 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 				snd_printddd("%d preload %d\n", s->number, preload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 				hpi_handle_error(hpi_outstream_write_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 						ds->h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 						&runtime->dma_area[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 						preload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 						&ds->format));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 				ds->pcm_buf_host_rw_ofs = preload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			if (card->support_grouping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 				snd_printdd("%d group\n", s->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 				e = hpi_stream_group_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 					dpcm->h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 					ds->h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 				if (!e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 					snd_pcm_trigger_done(s, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 					hpi_handle_error(e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		/* start the master stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		card->pcm_start(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			!card->can_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			hpi_handle_error(hpi_stream_start(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		snd_printdd("%s trigger stop\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		card->pcm_stop(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			if (snd_pcm_substream_chip(s) != card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			/* don't link Cap and Play */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 			if (substream->stream != s->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			/*? workaround linked streams don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			transition to SETUP 20070706*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			if (card->support_grouping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				snd_printdd("%d group\n", s->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 				snd_pcm_trigger_done(s, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		/* _prepare and _hwparams reset the stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 				hpi_outstream_reset(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		if (card->support_grouping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		snd_printdd("%s trigger pause release\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		card->pcm_start(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		hpi_handle_error(hpi_stream_start(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		snd_printdd("%s trigger pause push\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		card->pcm_stop(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		snd_printd(KERN_ERR "\tINVALID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) /*algorithm outline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)  Without linking degenerates to getting single stream pos etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)  Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) pcm_buf_dma_ofs=get_buf_pos(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) for_each_linked_stream(s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	pcm_buf_dma_ofs=get_buf_pos(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) for_each_linked_stream(s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	s->pcm_buf_dma_ofs = min_buf_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	if (new_data > period_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		if (mmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			irq_pos = (irq_pos + period_bytes) % buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			if (playback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 				write(period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 				read(period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		snd_pcm_period_elapsed(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) /** Minimum of 2 modulo values.  Works correctly when the difference between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) * the values is less than half the modulus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) static inline unsigned int modulo_min(unsigned int a, unsigned int b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 					unsigned long int modulus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	unsigned int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	if (((a-b) % modulus) < (modulus/2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		result = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		result = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) /** Timer function, equivalent to interrupt service routine for cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) static void snd_card_asihpi_timer_function(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct snd_card_asihpi_pcm *dpcm = from_timer(dpcm, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	struct snd_pcm_substream *substream = dpcm->substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	struct snd_pcm_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	struct snd_pcm_substream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	unsigned int newdata = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	unsigned int remdata, xfercount, next_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	int first = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	int loops = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	u16 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	snd_pcm_debug_name(substream, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	/* find minimum newdata and buffer pos in group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		runtime = s->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		if (snd_pcm_substream_chip(s) != card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		/* don't link Cap and Play */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		if (substream->stream != s->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		hpi_handle_error(hpi_stream_get_info_ex(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 					ds->h_stream, &state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					&buffer_size, &bytes_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 					&samples_played, &on_card_bytes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		/* number of bytes in on-card buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		runtime->delay = on_card_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		if (!card->can_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			on_card_bytes = bytes_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			if (state == HPI_STATE_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				if (bytes_avail == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 					hpi_handle_error(hpi_stream_start(ds->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					snd_printdd("P%d start\n", s->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 					ds->drained_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			} else if (state == HPI_STATE_DRAINED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 				snd_printd(KERN_WARNING "P%d drained\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 						s->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 				ds->drained_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				if (ds->drained_count > 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 					snd_pcm_stop_xrun(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 				ds->drained_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		if (first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			/* can't statically init min when wrap is involved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			min_buf_pos = pcm_buf_dma_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 			min_buf_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 				modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			newdata = min(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 				(pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 				newdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		snd_printddd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			"timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			name, s->number, state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			ds->pcm_buf_elapsed_dma_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			ds->pcm_buf_host_rw_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			pcm_buf_dma_ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 			(int)bytes_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			(int)on_card_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			buffer_size-bytes_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			(unsigned long)frames_to_bytes(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 						runtime->status->hw_ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			(unsigned long)frames_to_bytes(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 						runtime->control->appl_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		loops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	pcm_buf_dma_ofs = min_buf_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	remdata = newdata % dpcm->period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	xfercount = newdata - remdata; /* a multiple of period_bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	/* come back when on_card_bytes has decreased enough to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	   write to happen, or when data has been consumed to make another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	   period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (xfercount && (on_card_bytes  > dpcm->period_bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	next_jiffies = max(next_jiffies, 1U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	dpcm->timer.expires = jiffies + next_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	snd_printddd("timer2, jif=%d, buf_pos=%d, newdata=%d, xfer=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	snd_pcm_group_for_each_entry(s, substream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		/* don't link Cap and Play */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		if (substream->stream != s->stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		/* Store dma offset for use by pointer callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		if (xfercount &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			/* Limit use of on card fifo for playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			((on_card_bytes <= ds->period_bytes) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			(s->stream == SNDRV_PCM_STREAM_CAPTURE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			unsigned int xfer1, xfer2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			char *pd = &s->runtime->dma_area[buf_ofs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			if (card->can_dma) { /* buffer wrap is handled at lower level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 				xfer1 = xfercount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				xfer2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 				xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				xfer2 = xfercount - xfer1;
^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) 			if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 				snd_printddd("write1, P=%d, xfer=%d, buf_ofs=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 					s->number, xfer1, buf_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 					hpi_outstream_write_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 						ds->h_stream, pd, xfer1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 						&ds->format));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 				if (xfer2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 					pd = s->runtime->dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 					snd_printddd("write2, P=%d, xfer=%d, buf_ofs=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 							s->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 							xfercount - xfer1, buf_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 					hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 						hpi_outstream_write_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 							ds->h_stream, pd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 							xfercount - xfer1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 							&ds->format));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				snd_printddd("read1, C=%d, xfer=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 					s->number, xfer1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 				hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 					hpi_instream_read_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 						ds->h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 						pd, xfer1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 				if (xfer2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 					pd = s->runtime->dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 					snd_printddd("read2, C=%d, xfer=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 						s->number, xfer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 					hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 						hpi_instream_read_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 							ds->h_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 							pd, xfer2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			/* ? host_rw_ofs always ahead of elapsed_dma_ofs by preload size? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			ds->pcm_buf_host_rw_ofs += xfercount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			ds->pcm_buf_elapsed_dma_ofs += xfercount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			snd_pcm_period_elapsed(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	if (!card->hpi->interrupt_mode && dpcm->respawn_timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		add_timer(&dpcm->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) static void snd_card_asihpi_isr(struct hpi_adapter *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct snd_card_asihpi *asihpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	if (asihpi->llmode_streampriv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		snd_card_asihpi_timer_function(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 			&asihpi->llmode_streampriv->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) /***************************** PLAYBACK OPS ****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 					    substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	snd_printdd("P%d prepare\n", substream->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	dpcm->pcm_buf_host_rw_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	dpcm->pcm_buf_dma_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	dpcm->pcm_buf_elapsed_dma_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	return 0;
^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) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	snd_pcm_uframes_t ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	snd_pcm_debug_name(substream, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs  % dpcm->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	snd_printddd("%s, pointer=%ld\n", name, (unsigned long)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 						u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	struct hpi_format hpi_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	u16 format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	u32 sample_rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	u64 formats = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	/* on cards without SRC, must query at valid rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	* maybe set by external sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	err = hpi_mixer_get_control(asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 				  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 				  HPI_CONTROL_SAMPLECLOCK, &h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		err = hpi_sample_clock_get_sample_rate(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 				&sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	for (format = HPI_FORMAT_PCM8_UNSIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	     format <= HPI_FORMAT_PCM24_SIGNED; format++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 					format, sample_rate, 128000, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 			err = hpi_outstream_query_format(h_stream, &hpi_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	return formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	struct snd_card_asihpi_pcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	struct snd_pcm_hardware snd_card_asihpi_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if (dpcm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	err = hpi_outstream_open(card->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 			      substream->number, &dpcm->h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	hpi_handle_error(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		kfree(dpcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	/*? also check ASI5000 samplerate source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	    If external, only support external rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	    If internal and other stream playing, can't switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	dpcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	runtime->private_data = dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	runtime->private_free = snd_card_asihpi_runtime_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (!card->hpi->interrupt_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		snd_card_asihpi_playback.periods_min = PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		size_t pbmin = card->update_interval_frames *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			card->out_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		snd_card_asihpi_playback.period_bytes_min = pbmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		snd_card_asihpi_playback.periods_min = PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / pbmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	/* snd_card_asihpi_playback.fifo_size = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	snd_card_asihpi_playback.channels_max = card->out_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	snd_card_asihpi_playback.channels_min = card->out_min_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	snd_card_asihpi_playback.formats =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			snd_card_asihpi_playback_formats(card, dpcm->h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 					SNDRV_PCM_INFO_DOUBLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 					SNDRV_PCM_INFO_BATCH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 					SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 					SNDRV_PCM_INFO_PAUSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 					SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 					SNDRV_PCM_INFO_MMAP_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if (card->support_grouping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		snd_pcm_set_sync(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	/* struct is copied, so can create initializer dynamically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	runtime->hw = snd_card_asihpi_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	if (card->can_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		err = snd_pcm_hw_constraint_pow2(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 					SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		card->update_interval_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		card->update_interval_frames, UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	snd_printdd("playback open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	snd_printdd("playback close\n");
^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) static const struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	.open = snd_card_asihpi_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	.close = snd_card_asihpi_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	.hw_params = snd_card_asihpi_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	.hw_free = snd_card_asihpi_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	.prepare = snd_card_asihpi_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	.trigger = snd_card_asihpi_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	.pointer = snd_card_asihpi_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /***************************** CAPTURE OPS ****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	snd_pcm_debug_name(substream, name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	snd_printddd("%s, pointer=%d\n", name, dpcm->pcm_buf_dma_ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	/* NOTE Unlike playback can't use actual samples_played
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		for the capture position, because those samples aren't yet in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		the local buffer available for reading.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	dpcm->pcm_buf_host_rw_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	dpcm->pcm_buf_dma_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	dpcm->pcm_buf_elapsed_dma_ofs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	snd_printdd("Capture Prepare %d\n", substream->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 					u32 h_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	struct hpi_format hpi_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	u16 format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	u32 sample_rate = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	u64 formats = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	/* on cards without SRC, must query at valid rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		maybe set by external sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	err = hpi_mixer_get_control(asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 				  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 				  HPI_CONTROL_SAMPLECLOCK, &h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		err = hpi_sample_clock_get_sample_rate(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			&sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	for (format = HPI_FORMAT_PCM8_UNSIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		format <= HPI_FORMAT_PCM24_SIGNED; format++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 					format, sample_rate, 128000, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			err = hpi_instream_query_format(h_stream, &hpi_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	return formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	struct snd_card_asihpi_pcm *dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	struct snd_pcm_hardware snd_card_asihpi_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	if (dpcm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	snd_printdd("capture open adapter %d stream %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			card->hpi->adapter->index, substream->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	err = hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	    hpi_instream_open(card->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			     substream->number, &dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		kfree(dpcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	dpcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	runtime->private_data = dpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	runtime->private_free = snd_card_asihpi_runtime_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	if (!card->hpi->interrupt_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		snd_card_asihpi_capture.periods_min = PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		size_t pbmin = card->update_interval_frames *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			card->out_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		snd_card_asihpi_capture.period_bytes_min = pbmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		snd_card_asihpi_capture.periods_min = PERIODS_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / pbmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	/* snd_card_asihpi_capture.fifo_size = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	snd_card_asihpi_capture.channels_max = card->in_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	snd_card_asihpi_capture.channels_min = card->in_min_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	snd_card_asihpi_capture.formats =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		snd_card_asihpi_capture_formats(card, dpcm->h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 					SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 					SNDRV_PCM_INFO_MMAP_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	if (card->support_grouping)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	runtime->hw = snd_card_asihpi_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (card->can_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		err = snd_pcm_hw_constraint_pow2(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 					SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		card->update_interval_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		card->update_interval_frames, UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	snd_pcm_set_sync(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	hpi_handle_error(hpi_instream_close(dpcm->h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static const struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	.open = snd_card_asihpi_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	.close = snd_card_asihpi_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	.hw_params = snd_card_asihpi_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	.hw_free = snd_card_asihpi_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	.prepare = snd_card_asihpi_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	.trigger = snd_card_asihpi_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	.pointer = snd_card_asihpi_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static int snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	u16 num_instreams, num_outstreams, x16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	u32 x32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			&num_outstreams, &num_instreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			&x16, &x32, &x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 			num_outstreams,	num_instreams, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	/* pointer to ops struct is stored, dont change ops afterwards! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 			&snd_card_asihpi_playback_mmap_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 			&snd_card_asihpi_capture_mmap_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	pcm->private_data = asihpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	strcpy(pcm->name, "Asihpi PCM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	/*? do we want to emulate MMAP for non-BBM cards?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 				       &asihpi->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 				       64*1024, BUFFER_BYTES_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) /***************************** MIXER CONTROLS ****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct hpi_control {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	u16 control_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	u16 src_node_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	u16 src_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	u16 dst_node_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	u16 dst_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	u16 band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* copied to snd_ctl_elem_id.name[44]; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static const char * const asihpi_tuner_band_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	"invalid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	"AM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	"FM mono",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	"TV NTSC-M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	"FM stereo",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	"AUX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	"TV PAL BG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	"TV PAL I",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	"TV PAL DK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	"TV SECAM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	"TV DAB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* Number of strings must match the enumerations for HPI_TUNER_BAND in hpi.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) compile_time_assert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	(ARRAY_SIZE(asihpi_tuner_band_names) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		(HPI_TUNER_BAND_LAST+1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	assert_tuner_band_names_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static const char * const asihpi_src_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	"no source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	"PCM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	"Line",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	"Digital",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	"Tuner",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	"RF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	"Clock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	"Bitstream",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	"Mic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	"Net",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	"Analog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	"Adapter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	"RTP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	"Internal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	"AVB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	"BLU-Link"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /* Number of strings must match the enumerations for HPI_SOURCENODES in hpi.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) compile_time_assert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	(ARRAY_SIZE(asihpi_src_names) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		(HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	assert_src_names_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static const char * const asihpi_dst_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	"no destination",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	"PCM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	"Line",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	"Digital",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	"RF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	"Speaker",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	"Net",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	"Analog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	"RTP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	"AVB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	"Internal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	"BLU-Link"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /* Number of strings must match the enumerations for HPI_DESTNODES in hpi.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) compile_time_assert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	(ARRAY_SIZE(asihpi_dst_names) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		(HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	assert_dst_names_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 				struct snd_card_asihpi *asihpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	else if (mixer_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		dev_info(&asihpi->pci->dev, "added %s(%d)\n", ctl->name, ctl->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* Convert HPI control name and location into ALSA control name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 				struct hpi_control *hpi_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 				char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	char *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	memset(snd_control, 0, sizeof(*snd_control));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	snd_control->name = hpi_ctl->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	snd_control->private_value = hpi_ctl->h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	snd_control->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		dir = ""; /* clock is neither capture nor playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		dir = "Capture ";  /* On or towards a PCM capture destination*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		(!hpi_ctl->dst_node_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		dir = "Capture "; /* On a source node that is not PCM playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	else if (hpi_ctl->src_node_type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		(hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		(hpi_ctl->dst_node_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		dir = "Monitor Playback "; /* Between an input and an output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		dir = "Playback "; /* PCM Playback source, or  output node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			asihpi_src_names[hpi_ctl->src_node_type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 			hpi_ctl->src_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 			asihpi_dst_names[hpi_ctl->dst_node_type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			hpi_ctl->dst_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 			dir, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	else if (hpi_ctl->dst_node_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		sprintf(hpi_ctl->name, "%s %d %s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		asihpi_dst_names[hpi_ctl->dst_node_type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		hpi_ctl->dst_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		dir, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		sprintf(hpi_ctl->name, "%s %d %s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		asihpi_src_names[hpi_ctl->src_node_type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		hpi_ctl->src_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		dir, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	/* printk(KERN_INFO "Adding %s %d to %d ",  hpi_ctl->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 		hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)    Volume controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) #define VOL_STEP_mB 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	/* native gains are in millibels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	short min_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	short max_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	short step_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	err = hpi_volume_query_range(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 			&min_gain_mB, &max_gain_mB, &step_gain_mB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		max_gain_mB = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		min_gain_mB = -10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		step_gain_mB = VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	err = hpi_meter_query_channels(h_control, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		count = HPI_MAX_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	uinfo->count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	short an_gain_mB[HPI_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	short an_gain_mB[HPI_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	an_gain_mB[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	    (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	an_gain_mB[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	    (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	/*  change = asihpi->mixer_volume[addr][0] != left ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	   asihpi->mixer_volume[addr][1] != right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) #define snd_asihpi_volume_mute_info	snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	u32 mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	ucontrol->value.integer.value[0] = mute ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	/* HPI currently only supports all or none muting of multichannel volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	int mute =  ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	hpi_handle_error(hpi_volume_set_mute(h_control, mute));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 				 struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	u32 mute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 				SNDRV_CTL_ELEM_ACCESS_TLV_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	snd_control.info = snd_asihpi_volume_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	snd_control.get = snd_asihpi_volume_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	snd_control.put = snd_asihpi_volume_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	snd_control.tlv.p = db_scale_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	err = ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 		snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		snd_control.info = snd_asihpi_volume_mute_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		snd_control.get = snd_asihpi_volume_mute_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		snd_control.put = snd_asihpi_volume_mute_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		err = ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)    Level controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	short min_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	short max_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	short step_gain_mB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	    hpi_level_query_range(h_control, &min_gain_mB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 			       &max_gain_mB, &step_gain_mB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		max_gain_mB = 2400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		min_gain_mB = -1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		step_gain_mB = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	short an_gain_mB[HPI_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	    an_gain_mB[0] / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	ucontrol->value.integer.value[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	    an_gain_mB[1] / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	short an_gain_mB[HPI_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	an_gain_mB[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	    (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	an_gain_mB[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	    (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	/*  change = asihpi->mixer_level[addr][0] != left ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	   asihpi->mixer_level[addr][1] != right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 				struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	/* can't use 'volume' cos some nodes have volume as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 				SNDRV_CTL_ELEM_ACCESS_TLV_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	snd_control.info = snd_asihpi_level_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	snd_control.get = snd_asihpi_level_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	snd_control.put = snd_asihpi_level_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	snd_control.tlv.p = db_scale_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)    AESEBU controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) /* AESEBU format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static const char * const asihpi_aesebu_format_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	"N/A", "S/PDIF", "AES/EBU" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 			struct snd_ctl_elem_value *ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			u16 (*func)(u32, u16 *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	u16 source, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	err = func(h_control, &source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	/* default to N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	ucontrol->value.enumerated.item[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	/* return success but set the control to N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	if (source == HPI_AESEBU_FORMAT_SPDIF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		ucontrol->value.enumerated.item[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	if (source == HPI_AESEBU_FORMAT_AESEBU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		ucontrol->value.enumerated.item[0] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 			struct snd_ctl_elem_value *ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 			 u16 (*func)(u32, u16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	/* default to S/PDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	u16 source = HPI_AESEBU_FORMAT_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	if (ucontrol->value.enumerated.item[0] == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		source = HPI_AESEBU_FORMAT_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	if (ucontrol->value.enumerated.item[0] == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		source = HPI_AESEBU_FORMAT_AESEBU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	if (func(h_control, source) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 				 struct snd_ctl_elem_value *ucontrol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 					hpi_aesebu_receiver_get_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 				 struct snd_ctl_elem_value *ucontrol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 					hpi_aesebu_receiver_set_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	uinfo->value.integer.max = 0X1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	uinfo->value.integer.step = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 				 struct snd_ctl_elem_value *ucontrol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	hpi_handle_error(hpi_aesebu_receiver_get_error_status(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 					 h_control, &status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	ucontrol->value.integer.value[0] = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 				    struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	snd_control.info = snd_asihpi_aesebu_format_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	snd_control.get = snd_asihpi_aesebu_rx_format_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	snd_control.put = snd_asihpi_aesebu_rx_format_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	if (ctl_add(card, &snd_control, asihpi) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	snd_control.access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	    SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	snd_control.info = snd_asihpi_aesebu_rxstatus_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	snd_control.get = snd_asihpi_aesebu_rxstatus_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 				 struct snd_ctl_elem_value *ucontrol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 					hpi_aesebu_transmitter_get_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 				 struct snd_ctl_elem_value *ucontrol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 					hpi_aesebu_transmitter_set_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 				    struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	snd_control.info = snd_asihpi_aesebu_format_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	snd_control.get = snd_asihpi_aesebu_tx_format_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	snd_control.put = snd_asihpi_aesebu_tx_format_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)    Tuner controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) /* Gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	short idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	u16 gain_range[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	for (idx = 0; idx < 3; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		err = hpi_tuner_query_gain(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 					  idx, &gain_range[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	short gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	short gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /* Band  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 					u16 *band_list, u32 len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	u16 err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		err = hpi_tuner_query_band(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 				h_control, i, &band_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	u16 tuner_bands[HPI_TUNER_BAND_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	int num_bands = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 				HPI_TUNER_BAND_LAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	if (num_bands < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		return num_bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	u16 band, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	u16 tuner_bands[HPI_TUNER_BAND_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	__always_unused u32 num_bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 				HPI_TUNER_BAND_LAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	hpi_handle_error(hpi_tuner_get_band(h_control, &band));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	ucontrol->value.enumerated.item[0] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		if (tuner_bands[idx] == band) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 			ucontrol->value.enumerated.item[0] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	u16 band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	u16 tuner_bands[HPI_TUNER_BAND_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	__always_unused u32 num_bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			HPI_TUNER_BAND_LAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	idx = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	if (idx >= ARRAY_SIZE(tuner_bands))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 		idx = ARRAY_SIZE(tuner_bands) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	band = tuner_bands[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	hpi_handle_error(hpi_tuner_set_band(h_control, band));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) /* Freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	u16 tuner_bands[HPI_TUNER_BAND_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	u16 num_bands = 0, band_iter, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	u32 freq_range[3], temp_freq_range[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 			HPI_TUNER_BAND_LAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	freq_range[0] = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	freq_range[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	freq_range[2] = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	for (band_iter = 0; band_iter < num_bands; band_iter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		for (idx = 0; idx < 3; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			err = hpi_tuner_query_frequency(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 				idx, tuner_bands[band_iter],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 				&temp_freq_range[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 			if (err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 		/* skip band with bogus stepping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 		if (temp_freq_range[2] <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		if (temp_freq_range[0] < freq_range[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 			freq_range[0] = temp_freq_range[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		if (temp_freq_range[1] > freq_range[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 			freq_range[1] = temp_freq_range[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		if (temp_freq_range[2] < freq_range[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 			freq_range[2] = temp_freq_range[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	uinfo->value.integer.min = ((int)freq_range[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	uinfo->value.integer.max = ((int)freq_range[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	uinfo->value.integer.step = ((int)freq_range[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	ucontrol->value.integer.value[0] = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	freq = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) /* Tuner control group initializer  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 				struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	snd_control.private_value = hpi_ctl->h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 		asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		snd_control.info = snd_asihpi_tuner_gain_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		snd_control.get = snd_asihpi_tuner_gain_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		snd_control.put = snd_asihpi_tuner_gain_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		if (ctl_add(card, &snd_control, asihpi) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	snd_control.info = snd_asihpi_tuner_band_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	snd_control.get = snd_asihpi_tuner_band_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	snd_control.put = snd_asihpi_tuner_band_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	if (ctl_add(card, &snd_control, asihpi) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	snd_control.info = snd_asihpi_tuner_freq_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	snd_control.get = snd_asihpi_tuner_freq_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	snd_control.put = snd_asihpi_tuner_freq_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)    Meter controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	err = hpi_meter_query_channels(h_control, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 		count = HPI_MAX_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	uinfo->count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	uinfo->value.integer.max = 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) /* linear values for 10dB steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) static const int log2lin[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	0x7FFFFFFF, /* 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	679093956,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	214748365,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	 67909396,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	 21474837,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	  6790940,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	  2147484, /* -60dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	   679094,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	   214748, /* -80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	    67909,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	    21475, /* -100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	     6791,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	     2147,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	      679,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	      214,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	       68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	       21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	short an_gain_mB[HPI_MAX_CHANNELS], i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	u16 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	err = hpi_meter_get_peak(h_control, an_gain_mB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	for (i = 0; i < HPI_MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 			ucontrol->value.integer.value[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		} else if (an_gain_mB[i] >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 			ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 				an_gain_mB[i] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 			/* -ve is log value in millibels < -60dB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 			* convert to (roughly!) linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 			ucontrol->value.integer.value[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 					log2lin[an_gain_mB[i] / -1000];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 				struct hpi_control *hpi_ctl, int subidx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	snd_control.access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	    SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	snd_control.info = snd_asihpi_meter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	snd_control.get = snd_asihpi_meter_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	snd_control.index = subidx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)    Multiplexer controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	u32 h_control = snd_control->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	struct hpi_control hpi_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	int s, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	for (s = 0; s < 32; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		err = hpi_multiplexer_query_source(h_control, s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 						  &hpi_ctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 						  src_node_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 						  &hpi_ctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 						  src_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			       struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	u16 src_node_type, src_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	uinfo->value.enumerated.items =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	    snd_card_asihpi_mux_count_sources(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		uinfo->value.enumerated.item =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		    uinfo->value.enumerated.items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	hpi_multiplexer_query_source(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 				     uinfo->value.enumerated.item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 				     &src_node_type, &src_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	sprintf(uinfo->value.enumerated.name, "%s %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		src_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	u16 source_type, source_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	u16 src_node_type, src_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	hpi_handle_error(hpi_multiplexer_get_source(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 				&source_type, &source_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	/* Should cache this search result! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	for (s = 0; s < 256; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		if (hpi_multiplexer_query_source(h_control, s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 					    &src_node_type, &src_node_index))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		if ((source_type == src_node_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		    && (source_index == src_node_index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 			ucontrol->value.enumerated.item[0] = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	snd_printd(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		"Control %x failed to match mux source %hu %hu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		h_control, source_type, source_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	ucontrol->value.enumerated.item[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	u16 source_type, source_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	u16 e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	e = hpi_multiplexer_query_source(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 				    ucontrol->value.enumerated.item[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 				    &source_type, &source_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		hpi_handle_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 			hpi_multiplexer_set_source(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 						source_type, source_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) static int  snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 			       struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	snd_control.info = snd_asihpi_mux_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	snd_control.get = snd_asihpi_mux_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	snd_control.put = snd_asihpi_mux_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)    Channel mode controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 				 struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		"invalid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		"Normal", "Swap",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		"From Left", "From Right",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		"To Left", "To Right"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	u16 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	const char *mapped_names[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	int valid_modes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	/* HPI channel mode values can be from 1 to 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	Some adapters only support a contiguous subset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		if (!hpi_channel_mode_query_mode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 			h_control, i, &mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 			mapped_names[valid_modes] = mode_names[mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 			valid_modes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	if (!valid_modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	u16 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	if (hpi_channel_mode_get(h_control, &mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 		mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	ucontrol->value.enumerated.item[0] = mode - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 				struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	hpi_handle_error(hpi_channel_mode_set(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 			   ucontrol->value.enumerated.item[0] + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 				struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	struct snd_card *card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	snd_control.info = snd_asihpi_cmode_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	snd_control.get = snd_asihpi_cmode_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	snd_control.put = snd_asihpi_cmode_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)    Sampleclock source  controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) static const char * const sampleclock_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	"N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	"SMPTE", "Digital1", "Auto", "Network", "Invalid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	"Prev Module", "BLU-Link",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	"Digital2", "Digital3", "Digital4", "Digital5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	"Digital6", "Digital7", "Digital8"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	/* Number of strings must match expected enumerated values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	compile_time_assert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		(ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		assert_sampleclock_sources_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	struct snd_card_asihpi *asihpi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 			(struct snd_card_asihpi *)(kcontrol->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	struct clk_cache *clkcache = &asihpi->cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	uinfo->value.enumerated.items = clkcache->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		uinfo->value.enumerated.item =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 				uinfo->value.enumerated.items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	strcpy(uinfo->value.enumerated.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	       clkcache->s[uinfo->value.enumerated.item].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	struct snd_card_asihpi *asihpi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 			(struct snd_card_asihpi *)(kcontrol->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	struct clk_cache *clkcache = &asihpi->cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	u16 source, srcindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	ucontrol->value.enumerated.item[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	if (hpi_sample_clock_get_source(h_control, &source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		source = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 		if (hpi_sample_clock_get_source_index(h_control, &srcindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 			srcindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	for (i = 0; i < clkcache->count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		if ((clkcache->s[i].source == source) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 			(clkcache->s[i].index == srcindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	ucontrol->value.enumerated.item[0] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	struct snd_card_asihpi *asihpi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 			(struct snd_card_asihpi *)(kcontrol->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	struct clk_cache *clkcache = &asihpi->cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	unsigned int item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	item = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	if (item >= clkcache->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		item = clkcache->count-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	hpi_handle_error(hpi_sample_clock_set_source(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 				h_control, clkcache->s[item].source));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 		hpi_handle_error(hpi_sample_clock_set_source_index(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 				h_control, clkcache->s[item].index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)    Clkrate controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) /* Need to change this to enumerated control with list of rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 				   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	uinfo->value.integer.min = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	uinfo->value.integer.max = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	uinfo->value.integer.step = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 				  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	u32 rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	u16 e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	e = hpi_sample_clock_get_local_rate(h_control, &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		ucontrol->value.integer.value[0] = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		ucontrol->value.integer.value[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 				  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	/*  change = asihpi->mixer_clkrate[addr][0] != left ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	   asihpi->mixer_clkrate[addr][1] != right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	change = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 				      ucontrol->value.integer.value[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 				   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	uinfo->value.integer.min = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	uinfo->value.integer.max = 192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	uinfo->value.integer.step = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 				  struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	u32 h_control = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	u32 rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	u16 e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	e = hpi_sample_clock_get_sample_rate(h_control, &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 		ucontrol->value.integer.value[0] = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		ucontrol->value.integer.value[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 				      struct hpi_control *hpi_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	struct snd_kcontrol_new snd_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	struct clk_cache *clkcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	u32 hSC =  hpi_ctl->h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	int has_aes_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	u16 source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	if (snd_BUG_ON(!asihpi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	clkcache = &asihpi->cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	snd_control.private_value = hpi_ctl->h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	clkcache->has_local = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 		if  (hpi_sample_clock_query_source(hSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 				i, &source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 		clkcache->s[i].source = source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		clkcache->s[i].index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		clkcache->s[i].name = sampleclock_sources[source];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			has_aes_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 		if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 			clkcache->has_local = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	if (has_aes_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 		/* already will have picked up index 0 above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		for (j = 1; j < 8; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 			if (hpi_sample_clock_query_source_index(hSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 				j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 				&source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 			clkcache->s[i].source =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 				HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 			clkcache->s[i].index = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 			clkcache->s[i].name = sampleclock_sources[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 					j+HPI_SAMPLECLOCK_SOURCE_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	clkcache->count = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	snd_control.info = snd_asihpi_clksrc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	snd_control.get = snd_asihpi_clksrc_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	snd_control.put = snd_asihpi_clksrc_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	if (ctl_add(card, &snd_control, asihpi) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	if (clkcache->has_local) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		snd_control.info = snd_asihpi_clklocal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		snd_control.get = snd_asihpi_clklocal_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		snd_control.put = snd_asihpi_clklocal_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		if (ctl_add(card, &snd_control, asihpi) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	snd_control.access =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	    SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	snd_control.info = snd_asihpi_clkrate_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	snd_control.get = snd_asihpi_clkrate_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	return ctl_add(card, &snd_control, asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)    Mixer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	unsigned int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	unsigned int subindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	struct hpi_control hpi_ctl, prev_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	if (snd_BUG_ON(!asihpi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	card = asihpi->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	strcpy(card->mixername, "Asihpi Mixer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	    hpi_mixer_open(asihpi->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 			  &asihpi->h_mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	hpi_handle_error(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		return -err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	memset(&prev_ctl, 0, sizeof(prev_ctl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	prev_ctl.control_type = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	for (idx = 0; idx < 2000; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 		err = hpi_mixer_get_control_by_index(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 				asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 				idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 				&hpi_ctl.src_node_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				&hpi_ctl.src_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 				&hpi_ctl.dst_node_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 				&hpi_ctl.dst_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 				&hpi_ctl.control_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 				&hpi_ctl.h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 			if (err == HPI_ERROR_CONTROL_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 				if (mixer_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 					dev_info(&asihpi->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 						   "Disabled HPI Control(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 						   idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 		hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 		hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		/* ASI50xx in SSX mode has multiple meters on the same node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		   Use subindex to create distinct ALSA controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 		   for any duplicated controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		if ((hpi_ctl.control_type == prev_ctl.control_type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 		    (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		    (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		    (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		    (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 			subindex++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 			subindex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 		prev_ctl = hpi_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 		switch (hpi_ctl.control_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		case HPI_CONTROL_VOLUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 			err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		case HPI_CONTROL_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			err = snd_asihpi_level_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		case HPI_CONTROL_MULTIPLEXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		case HPI_CONTROL_CHANNEL_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 			err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		case HPI_CONTROL_METER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 			err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 		case HPI_CONTROL_SAMPLECLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 			err = snd_asihpi_sampleclock_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 						asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		case HPI_CONTROL_CONNECTION:	/* ignore these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 		case HPI_CONTROL_TUNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 			err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 		case HPI_CONTROL_AESEBU_TRANSMITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 			err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		case HPI_CONTROL_AESEBU_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 			err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 		case HPI_CONTROL_VOX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		case HPI_CONTROL_BITSTREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		case HPI_CONTROL_MICROPHONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 		case HPI_CONTROL_PARAMETRIC_EQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 		case HPI_CONTROL_COMPANDER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 			if (mixer_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 				dev_info(&asihpi->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 					"Untranslated HPI Control (%d) %d %d %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 					idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 					hpi_ctl.control_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 					hpi_ctl.src_node_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 					hpi_ctl.src_node_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 					hpi_ctl.dst_node_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 					hpi_ctl.dst_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	if (HPI_ERROR_INVALID_OBJ_INDEX != err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		hpi_handle_error(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)    /proc interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) snd_asihpi_proc_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	struct snd_card_asihpi *asihpi = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	u32 rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	u16 source = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	u16 num_outstreams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	u16 num_instreams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	u16 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	u32 serial_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	snd_iprintf(buffer, "ASIHPI driver proc file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 			&num_outstreams, &num_instreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 			&version, &serial_number, &type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 			"Adapter type ASI%4X\nHardware Index %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 			"%d outstreams\n%d instreams\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 			type, asihpi->hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 			num_outstreams, num_instreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 		"Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 		serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 		((version >> 13) * 100) + ((version >> 7) & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	err = hpi_mixer_get_control(asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 				  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 				  HPI_CONTROL_SAMPLECLOCK, &h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		err = hpi_sample_clock_get_sample_rate(h_control, &rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		err += hpi_sample_clock_get_source(h_control, &source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 			rate, sampleclock_sources[source]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	snd_card_ro_proc_new(asihpi->card, "info", asihpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 			     snd_asihpi_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)    HWDEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	if (enable_hpi_hwdep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	if (enable_hpi_hwdep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		return asihpi_hpi_release(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 				unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	if (enable_hpi_hwdep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		return asihpi_hpi_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) /* results in /dev/snd/hwC#D0 file for each card with index #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)    also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	struct snd_hwdep *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	strcpy(hw->name, "asihpi (HPI)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	hw->iface = SNDRV_HWDEP_IFACE_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	hw->ops.open = snd_asihpi_hpi_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	hw->ops.ioctl = snd_asihpi_hpi_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	hw->ops.release = snd_asihpi_hpi_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	hw->private_data = asihpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) /*------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)    CARD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)  ------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) static int snd_asihpi_probe(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 			    const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	struct hpi_adapter *hpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	struct snd_card_asihpi *asihpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	u32 h_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	u32 h_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	u32 adapter_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	/* Should this be enable[hpi->index] ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	/* Initialise low-level HPI driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	err = asihpi_adapter_probe(pci_dev, pci_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	hpi = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	adapter_index = hpi->adapter->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	/* first try to give the card the same index as its hardware index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	err = snd_card_new(&pci_dev->dev, adapter_index, id[adapter_index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 			   THIS_MODULE, sizeof(struct snd_card_asihpi), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		/* if that fails, try the default index==next available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		err = snd_card_new(&pci_dev->dev, index[dev], id[dev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 				   THIS_MODULE, sizeof(struct snd_card_asihpi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 				   &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		dev_warn(&pci_dev->dev, "Adapter index %d->ALSA index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 			adapter_index, card->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	asihpi = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	asihpi->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	asihpi->pci = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	asihpi->hpi = hpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	hpi->snd_card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	err = hpi_adapter_get_property(adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		HPI_ADAPTER_PROPERTY_CAPS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		NULL, &asihpi->support_grouping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		asihpi->support_grouping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 	err = hpi_adapter_get_property(adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		HPI_ADAPTER_PROPERTY_CAPS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		&asihpi->support_mrx, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		asihpi->support_mrx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	err = hpi_adapter_get_property(adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		HPI_ADAPTER_PROPERTY_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		NULL, &asihpi->update_interval_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 		asihpi->update_interval_frames = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	if (hpi->interrupt_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 		asihpi->pcm_start = snd_card_asihpi_pcm_int_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 		asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 		hpi->interrupt_callback = snd_card_asihpi_isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		asihpi->pcm_start = snd_card_asihpi_pcm_timer_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		asihpi->pcm_stop = snd_card_asihpi_pcm_timer_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	hpi_handle_error(hpi_instream_open(adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 			     0, &h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	err = hpi_instream_host_buffer_free(h_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	asihpi->can_dma = (!err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	hpi_handle_error(hpi_instream_close(h_stream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	if (!asihpi->can_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 		asihpi->update_interval_frames *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	err = hpi_adapter_get_property(adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		HPI_ADAPTER_PROPERTY_CURCHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		&asihpi->in_max_chans, &asihpi->out_max_chans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		asihpi->in_max_chans = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		asihpi->out_max_chans = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	if (asihpi->out_max_chans > 2) { /* assume LL mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		asihpi->out_min_chans = asihpi->out_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		asihpi->in_min_chans = asihpi->in_max_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		asihpi->support_grouping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 		asihpi->out_min_chans = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		asihpi->in_min_chans = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	dev_info(&pci_dev->dev, "Has dma:%d, grouping:%d, mrx:%d, uif:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 			asihpi->can_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 			asihpi->support_grouping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			asihpi->support_mrx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 			asihpi->update_interval_frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	      );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	err = snd_card_asihpi_pcm_new(asihpi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		dev_err(&pci_dev->dev, "pcm_new failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		goto __nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	err = snd_card_asihpi_mixer_new(asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		dev_err(&pci_dev->dev, "mixer_new failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		goto __nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	err = hpi_mixer_get_control(asihpi->h_mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 				  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 				  HPI_CONTROL_SAMPLECLOCK, &h_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		err = hpi_sample_clock_set_local_rate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 			h_control, adapter_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	snd_asihpi_proc_init(asihpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	/* always create, can be enabled or disabled dynamically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	    by enable_hwdep  module param*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	snd_asihpi_hpi_new(asihpi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 	strcpy(card->driver, "ASIHPI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	sprintf(card->shortname, "AudioScience ASI%4X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 			asihpi->hpi->adapter->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 	sprintf(card->longname, "%s %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 			card->shortname, adapter_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) __nodev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) static void snd_asihpi_remove(struct pci_dev *pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	/* Stop interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	if (hpi->interrupt_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		hpi->interrupt_callback = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 			HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	snd_card_free(hpi->snd_card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	hpi->snd_card = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	asihpi_adapter_remove(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) static const struct pci_device_id asihpi_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	{HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 		(kernel_ulong_t)HPI_6205},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	{HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 		HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		(kernel_ulong_t)HPI_6000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	{0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) static struct pci_driver driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	.name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	.id_table = asihpi_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	.probe = snd_asihpi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	.remove = snd_asihpi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) static int __init snd_asihpi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	asihpi_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	return pci_register_driver(&driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) static void __exit snd_asihpi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	pci_unregister_driver(&driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 	asihpi_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) module_init(snd_asihpi_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) module_exit(snd_asihpi_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)