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