Merge branch 'for-next' into for-linus

Prepare for 6.8 merge.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2024-01-08 08:17:18 +01:00
commit 821e2ac632
55 changed files with 4726 additions and 927 deletions

View File

@ -8272,11 +8272,14 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/joystick/fsia6b.c
FOCUSRITE SCARLETT GEN 2/3 MIXER DRIVER
FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett)
M: Geoffrey D. Bennett <g@b4.vu>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
W: https://github.com/geoffreybennett/scarlett-gen2
B: https://github.com/geoffreybennett/scarlett-gen2/issues
T: git https://github.com/geoffreybennett/scarlett-gen2.git
F: include/uapi/sound/scarlett2.h
F: sound/usb/mixer_scarlett2.c
FORCEDETH GIGABIT ETHERNET DRIVER

View File

@ -3065,6 +3065,7 @@
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
#define PCI_DEVICE_ID_INTEL_HDA_ARL 0x7728
#define PCI_DEVICE_ID_INTEL_HDA_RPL_S 0x7a50
#define PCI_DEVICE_ID_INTEL_HDA_ADL_S 0x7ad0
#define PCI_DEVICE_ID_INTEL_HDA_MTL 0x7e28

View File

@ -410,7 +410,7 @@ int snd_ac97_pcm_close(struct ac97_pcm *pcm);
int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
/* ad hoc AC97 device driver access */
extern struct bus_type ac97_bus_type;
extern const struct bus_type ac97_bus_type;
/* AC97 platform_data adding function */
static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)

View File

@ -141,6 +141,7 @@ struct hda_pcm_stream {
hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
u32 rates; /* supported rates */
u64 formats; /* supported formats (SNDRV_PCM_FMTBIT_) */
u32 subformats; /* for S32_LE format, SNDRV_PCM_SUBFMTBIT_* */
unsigned int maxbps; /* supported max. bit per sample */
const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
struct hda_pcm_ops ops;
@ -448,8 +449,8 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
#define snd_hda_codec_cleanup_stream(codec, nid) \
__snd_hda_codec_cleanup_stream(codec, nid, 0)
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, subfmtp, bpsp) \
snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, subfmtp, bpsp)
#define snd_hda_is_supported_format(codec, nid, fmt) \
snd_hdac_is_supported_format(&(codec)->core, nid, fmt)

View File

@ -33,7 +33,7 @@ struct hda_device_id;
/*
* exported bus type
*/
extern struct bus_type snd_hda_bus_type;
extern const struct bus_type snd_hda_bus_type;
/*
* generic arrays
@ -140,13 +140,14 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
hda_nid_t *conn_list, int max_conns);
int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
hda_nid_t *start_id);
unsigned int snd_hdac_calc_stream_format(unsigned int rate,
unsigned int channels,
snd_pcm_format_t format,
unsigned int maxbps,
unsigned short spdif_ctls);
unsigned int snd_hdac_stream_format_bits(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
unsigned int maxbits);
unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bits, unsigned int rate);
unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bits,
unsigned int rate, unsigned short spdif_ctls);
int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
u32 *ratesp, u64 *formatsp, u32 *subformatsp,
unsigned int *bpsp);
bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
unsigned int format);

View File

@ -32,6 +32,7 @@
struct snd_pcm_hardware {
unsigned int info; /* SNDRV_PCM_INFO_* */
u64 formats; /* SNDRV_PCM_FMTBIT_* */
u32 subformats; /* for S32_LE, SNDRV_PCM_SUBFMTBIT_* */
unsigned int rates; /* SNDRV_PCM_RATE_* */
unsigned int rate_min; /* min rate */
unsigned int rate_max; /* max rate */
@ -217,6 +218,12 @@ struct snd_pcm_ops {
#define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_BE
#endif
#define _SNDRV_PCM_SUBFMTBIT(fmt) BIT((__force int)SNDRV_PCM_SUBFORMAT_##fmt)
#define SNDRV_PCM_SUBFMTBIT_STD _SNDRV_PCM_SUBFMTBIT(STD)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_MAX _SNDRV_PCM_SUBFMTBIT(MSBITS_MAX)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_20 _SNDRV_PCM_SUBFMTBIT(MSBITS_20)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_24 _SNDRV_PCM_SUBFMTBIT(MSBITS_24)
struct snd_pcm_file {
struct snd_pcm_substream *substream;
int no_compat_mmap;

View File

@ -362,6 +362,8 @@ static inline int params_physical_width(const struct snd_pcm_hw_params *p)
return snd_pcm_format_physical_width(params_format(p));
}
int snd_pcm_hw_params_bits(const struct snd_pcm_hw_params *p);
static inline void
params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
{

View File

@ -620,6 +620,7 @@ enum snd_soc_trigger_order {
struct snd_soc_pcm_stream {
const char *stream_name;
u64 formats; /* SNDRV_PCM_FMTBIT_* */
u32 subformats; /* for S32_LE format, SNDRV_PCM_SUBFMTBIT_* */
unsigned int rates; /* SNDRV_PCM_RATE_* */
unsigned int rate_min; /* min rate */
unsigned int rate_max; /* max rate */

View File

@ -22,6 +22,7 @@
#define TAS2781_DRV_VER 1
#define SMARTAMP_MODULE_NAME "tas2781"
#define TAS2781_GLOBAL_ADDR 0x40
#define TAS2563_GLOBAL_ADDR 0x48
#define TASDEVICE_RATES (SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
SNDRV_PCM_RATE_88200)
@ -121,6 +122,8 @@ struct tasdevice_priv {
bool force_fwload_status;
bool playback_started;
bool isacpi;
unsigned int global_addr;
int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
const struct firmware *fmw, int offset);
int (*fw_parse_program_data)(struct tasdevice_priv *tas_priv,
@ -131,6 +134,9 @@ struct tasdevice_priv {
const struct firmware *fmw, int offset);
int (*tasdevice_load_block)(struct tasdevice_priv *tas_priv,
struct tasdev_blk *block);
int (*save_calibration)(struct tasdevice_priv *tas_priv);
void (*apply_calibration)(struct tasdevice_priv *tas_priv);
};
void tas2781_reset(struct tasdevice_priv *tas_dev);
@ -139,6 +145,8 @@ int tascodec_init(struct tasdevice_priv *tas_priv, void *codec,
struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c);
int tasdevice_init(struct tasdevice_priv *tas_priv);
void tasdevice_remove(struct tasdevice_priv *tas_priv);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
unsigned short chn, unsigned int reg, unsigned int *value);
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,

View File

@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
* *
*****************************************************************************/
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 16)
typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t;
@ -267,7 +267,10 @@ typedef int __bitwise snd_pcm_format_t;
typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX ((__force snd_pcm_subformat_t) 1)
#define SNDRV_PCM_SUBFORMAT_MSBITS_20 ((__force snd_pcm_subformat_t) 2)
#define SNDRV_PCM_SUBFORMAT_MSBITS_24 ((__force snd_pcm_subformat_t) 3)
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_MSBITS_24
#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */

View File

@ -0,0 +1,54 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* Focusrite Scarlett 2 Protocol Driver for ALSA
* (including Scarlett 2nd Gen, 3rd Gen, 4th Gen, Clarett USB, and
* Clarett+ series products)
*
* Copyright (c) 2023 by Geoffrey D. Bennett <g at b4.vu>
*/
#ifndef __UAPI_SOUND_SCARLETT2_H
#define __UAPI_SOUND_SCARLETT2_H
#include <linux/types.h>
#include <linux/ioctl.h>
#define SCARLETT2_HWDEP_MAJOR 1
#define SCARLETT2_HWDEP_MINOR 0
#define SCARLETT2_HWDEP_SUBMINOR 0
#define SCARLETT2_HWDEP_VERSION \
((SCARLETT2_HWDEP_MAJOR << 16) | \
(SCARLETT2_HWDEP_MINOR << 8) | \
SCARLETT2_HWDEP_SUBMINOR)
#define SCARLETT2_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF)
#define SCARLETT2_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF)
#define SCARLETT2_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF)
/* Get protocol version */
#define SCARLETT2_IOCTL_PVERSION _IOR('S', 0x60, int)
/* Reboot */
#define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61)
/* Select flash segment */
#define SCARLETT2_SEGMENT_ID_SETTINGS 0
#define SCARLETT2_SEGMENT_ID_FIRMWARE 1
#define SCARLETT2_SEGMENT_ID_COUNT 2
#define SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT _IOW('S', 0x62, int)
/* Erase selected flash segment */
#define SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT _IO('S', 0x63)
/* Get selected flash segment erase progress
* 1 through to num_blocks, or 255 for complete
*/
struct scarlett2_flash_segment_erase_progress {
unsigned char progress;
unsigned char num_blocks;
};
#define SCARLETT2_IOCTL_GET_ERASE_PROGRESS \
_IOR('S', 0x64, struct scarlett2_flash_segment_erase_progress)
#endif /* __UAPI_SOUND_SCARLETT2_H */

View File

@ -15,6 +15,7 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <sound/ac97_codec.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/controller.h>
#include <sound/ac97/regs.h>
@ -28,8 +29,6 @@ static DEFINE_MUTEX(ac97_controllers_mutex);
static DEFINE_IDR(ac97_adapter_idr);
static LIST_HEAD(ac97_controllers);
static struct bus_type ac97_bus_type;
static inline struct ac97_controller*
to_ac97_controller(struct device *ac97_adapter)
{
@ -531,7 +530,7 @@ static void ac97_bus_remove(struct device *dev)
pm_runtime_disable(dev);
}
static struct bus_type ac97_bus_type = {
const struct bus_type ac97_bus_type = {
.name = "ac97bus",
.dev_groups = ac97_dev_groups,
.match = ac97_bus_match,

View File

@ -75,7 +75,7 @@ int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
}
EXPORT_SYMBOL_GPL(snd_ac97_reset);
struct bus_type ac97_bus_type = {
const struct bus_type ac97_bus_type = {
.name = "ac97",
};

View File

@ -266,6 +266,9 @@ static const char * const snd_pcm_access_names[] = {
static const char * const snd_pcm_subformat_names[] = {
SUBFORMAT(STD),
SUBFORMAT(MSBITS_MAX),
SUBFORMAT(MSBITS_20),
SUBFORMAT(MSBITS_24),
};
static const char * const snd_pcm_tstamp_mode_names[] = {

View File

@ -1706,6 +1706,40 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
}
EXPORT_SYMBOL(snd_pcm_hw_param_last);
/**
* snd_pcm_hw_params_bits - Get the number of bits per the sample.
* @p: hardware parameters
*
* Return: The number of bits per sample based on the format,
* subformat and msbits the specified hw params has.
*/
int snd_pcm_hw_params_bits(const struct snd_pcm_hw_params *p)
{
snd_pcm_subformat_t subformat = params_subformat(p);
snd_pcm_format_t format = params_format(p);
switch (format) {
case SNDRV_PCM_FORMAT_S32_LE:
case SNDRV_PCM_FORMAT_U32_LE:
case SNDRV_PCM_FORMAT_S32_BE:
case SNDRV_PCM_FORMAT_U32_BE:
switch (subformat) {
case SNDRV_PCM_SUBFORMAT_MSBITS_20:
return 20;
case SNDRV_PCM_SUBFORMAT_MSBITS_24:
return 24;
case SNDRV_PCM_SUBFORMAT_MSBITS_MAX:
case SNDRV_PCM_SUBFORMAT_STD:
default:
break;
}
fallthrough;
default:
return snd_pcm_format_width(format);
}
}
EXPORT_SYMBOL(snd_pcm_hw_params_bits);
static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
void *arg)
{

View File

@ -479,6 +479,7 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
{
const struct snd_interval *i;
const struct snd_mask *m;
struct snd_mask *m_rw;
int err;
if (!params->msbits) {
@ -487,6 +488,22 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
params->msbits = snd_interval_value(i);
}
if (params->msbits) {
m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
if (snd_mask_single(m)) {
snd_pcm_format_t format = (__force snd_pcm_format_t)snd_mask_min(m);
if (snd_pcm_format_linear(format) &&
snd_pcm_format_width(format) != params->msbits) {
m_rw = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
snd_mask_reset(m_rw,
(__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
if (snd_mask_empty(m_rw))
return -EINVAL;
}
}
}
if (!params->rate_den) {
i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
if (snd_interval_single(i)) {
@ -2483,6 +2500,41 @@ static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
static int snd_pcm_hw_rule_subformats(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_mask *sfmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
struct snd_mask *fmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
u32 *subformats = rule->private;
snd_pcm_format_t f;
struct snd_mask m;
snd_mask_none(&m);
/* All PCMs support at least the default STD subformat. */
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_STD);
pcm_for_each_format(f) {
if (!snd_mask_test(fmask, (__force unsigned)f))
continue;
if (f == SNDRV_PCM_FORMAT_S32_LE && *subformats)
m.bits[0] |= *subformats;
else if (snd_pcm_format_linear(f))
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
}
return snd_mask_refine(sfmask, &m);
}
static int snd_pcm_hw_constraint_subformats(struct snd_pcm_runtime *runtime,
unsigned int cond, u32 *subformats)
{
return snd_pcm_hw_rule_add(runtime, cond, -1,
snd_pcm_hw_rule_subformats, (void *)subformats,
SNDRV_PCM_HW_PARAM_SUBFORMAT,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
}
static int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@ -2634,8 +2686,7 @@ static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
if (err < 0)
return err;
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT,
PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD));
err = snd_pcm_hw_constraint_subformats(runtime, 0, &hw->subformats);
if (err < 0)
return err;

View File

@ -442,7 +442,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
if (snd_BUG_ON(!pool))
return -EINVAL;
cellptr = kvmalloc_array(sizeof(struct snd_seq_event_cell), pool->size,
cellptr = kvmalloc_array(pool->size,
sizeof(struct snd_seq_event_cell),
GFP_KERNEL);
if (!cellptr)
return -ENOMEM;

View File

@ -76,7 +76,7 @@ static int hda_uevent(const struct device *dev, struct kobj_uevent_env *env)
return 0;
}
struct bus_type snd_hda_bus_type = {
const struct bus_type snd_hda_bus_type = {
.name = "hdaudio",
.match = hda_bus_match,
.uevent = hda_uevent,

View File

@ -13,6 +13,7 @@
#include <sound/hdaudio.h>
#include <sound/hda_regmap.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "local.h"
static void setup_fg_nodes(struct hdac_device *codec);
@ -725,32 +726,77 @@ static const struct hda_rate_tbl rate_bits[] = {
{ 0 } /* terminator */
};
/**
* snd_hdac_calc_stream_format - calculate the format bitset
* @rate: the sample rate
* @channels: the number of channels
* @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
* @maxbps: the max. bps
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
*
* Calculate the format bitset from the given rate, channels and th PCM format.
*
* Return zero if invalid.
*/
unsigned int snd_hdac_calc_stream_format(unsigned int rate,
unsigned int channels,
snd_pcm_format_t format,
unsigned int maxbps,
unsigned short spdif_ctls)
static snd_pcm_format_t snd_hdac_format_normalize(snd_pcm_format_t format)
{
int i;
unsigned int val = 0;
switch (format) {
case SNDRV_PCM_FORMAT_S20_LE:
case SNDRV_PCM_FORMAT_S24_LE:
return SNDRV_PCM_FORMAT_S32_LE;
for (i = 0; rate_bits[i].hz; i++)
case SNDRV_PCM_FORMAT_U20_LE:
case SNDRV_PCM_FORMAT_U24_LE:
return SNDRV_PCM_FORMAT_U32_LE;
case SNDRV_PCM_FORMAT_S20_BE:
case SNDRV_PCM_FORMAT_S24_BE:
return SNDRV_PCM_FORMAT_S32_BE;
case SNDRV_PCM_FORMAT_U20_BE:
case SNDRV_PCM_FORMAT_U24_BE:
return SNDRV_PCM_FORMAT_U32_BE;
default:
return format;
}
}
/**
* snd_hdac_stream_format_bits - obtain bits per sample value.
* @format: the PCM format.
* @subformat: the PCM subformat.
* @maxbits: the maximum bits per sample.
*
* Return: The number of bits per sample.
*/
unsigned int snd_hdac_stream_format_bits(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
unsigned int maxbits)
{
struct snd_pcm_hw_params params;
unsigned int bits;
memset(&params, 0, sizeof(params));
params_set_format(&params, snd_hdac_format_normalize(format));
snd_mask_set(hw_param_mask(&params, SNDRV_PCM_HW_PARAM_SUBFORMAT),
(__force unsigned int)subformat);
bits = snd_pcm_hw_params_bits(&params);
if (maxbits)
return min(bits, maxbits);
return bits;
}
EXPORT_SYMBOL_GPL(snd_hdac_stream_format_bits);
/**
* snd_hdac_stream_format - convert format parameters to SDxFMT value.
* @channels: the number of channels.
* @bits: bits per sample.
* @rate: the sample rate.
*
* Return: The format bitset or zero if invalid.
*/
unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bits, unsigned int rate)
{
unsigned int val = 0;
int i;
for (i = 0; rate_bits[i].hz; i++) {
if (rate_bits[i].hz == rate) {
val = rate_bits[i].hda_fmt;
break;
}
}
if (!rate_bits[i].hz)
return 0;
@ -758,7 +804,7 @@ unsigned int snd_hdac_calc_stream_format(unsigned int rate,
return 0;
val |= channels - 1;
switch (snd_pcm_format_width(format)) {
switch (bits) {
case 8:
val |= AC_FMT_BITS_8;
break;
@ -766,25 +812,42 @@ unsigned int snd_hdac_calc_stream_format(unsigned int rate,
val |= AC_FMT_BITS_16;
break;
case 20:
val |= AC_FMT_BITS_20;
break;
case 24:
val |= AC_FMT_BITS_24;
break;
case 32:
if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
val |= AC_FMT_BITS_32;
else if (maxbps >= 24)
val |= AC_FMT_BITS_24;
else
val |= AC_FMT_BITS_20;
val |= AC_FMT_BITS_32;
break;
default:
return 0;
}
if (spdif_ctls & AC_DIG1_NONAUDIO)
return val;
}
EXPORT_SYMBOL_GPL(snd_hdac_stream_format);
/**
* snd_hdac_spdif_stream_format - convert format parameters to SDxFMT value.
* @channels: the number of channels.
* @bits: bits per sample.
* @rate: the sample rate.
* @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant).
*
* Return: The format bitset or zero if invalid.
*/
unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bits,
unsigned int rate, unsigned short spdif_ctls)
{
unsigned int val = snd_hdac_stream_format(channels, bits, rate);
if (val && spdif_ctls & AC_DIG1_NONAUDIO)
val |= AC_FMT_TYPE_NON_PCM;
return val;
}
EXPORT_SYMBOL_GPL(snd_hdac_calc_stream_format);
EXPORT_SYMBOL_GPL(snd_hdac_spdif_stream_format);
static unsigned int query_pcm_param(struct hdac_device *codec, hda_nid_t nid)
{
@ -817,15 +880,17 @@ static unsigned int query_stream_param(struct hdac_device *codec, hda_nid_t nid)
* @nid: NID to query
* @ratesp: the pointer to store the detected rate bitflags
* @formatsp: the pointer to store the detected formats
* @subformatsp: the pointer to store the detected subformats for S32_LE format
* @bpsp: the pointer to store the detected format widths
*
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
* or @bsps argument is ignored.
* Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp,
* @subformatsp or @bpsp argument is ignored.
*
* Returns 0 if successful, otherwise a negative error code.
*/
int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
u32 *ratesp, u64 *formatsp, u32 *subformatsp,
unsigned int *bpsp)
{
unsigned int i, val, wcaps;
@ -848,9 +913,10 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
*ratesp = rates;
}
if (formatsp || bpsp) {
u64 formats = 0;
if (formatsp || subformatsp || bpsp) {
unsigned int streams, bps;
u32 subformats = 0;
u64 formats = 0;
streams = query_stream_param(codec, nid);
if (!streams)
@ -866,24 +932,24 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
formats |= SNDRV_PCM_FMTBIT_S16_LE;
bps = 16;
}
if (wcaps & AC_WCAP_DIGITAL) {
if (val & AC_SUPPCM_BITS_32)
formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
formats |= SNDRV_PCM_FMTBIT_S32_LE;
if (val & AC_SUPPCM_BITS_24)
bps = 24;
else if (val & AC_SUPPCM_BITS_20)
bps = 20;
} else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
AC_SUPPCM_BITS_32)) {
if (val & AC_SUPPCM_BITS_20) {
formats |= SNDRV_PCM_FMTBIT_S32_LE;
if (val & AC_SUPPCM_BITS_32)
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_20;
bps = 20;
}
if (val & AC_SUPPCM_BITS_24) {
formats |= SNDRV_PCM_FMTBIT_S32_LE;
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_24;
bps = 24;
}
if (val & AC_SUPPCM_BITS_32) {
if (wcaps & AC_WCAP_DIGITAL) {
formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
} else {
formats |= SNDRV_PCM_FMTBIT_S32_LE;
subformats |= SNDRV_PCM_SUBFMTBIT_MSBITS_MAX;
bps = 32;
else if (val & AC_SUPPCM_BITS_24)
bps = 24;
else if (val & AC_SUPPCM_BITS_20)
bps = 20;
}
}
}
#if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
@ -911,6 +977,8 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
}
if (formatsp)
*formatsp = formats;
if (subformatsp)
*subformatsp = subformats;
if (bpsp)
*bpsp = bps;
}

View File

@ -671,17 +671,15 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
struct hdac_stream *s;
bool inited = false;
u64 cycle_last = 0;
int i = 0;
list_for_each_entry(s, &bus->stream_list, list) {
if (streams & (1 << i)) {
if ((streams & (1 << s->index))) {
azx_timecounter_init(s, inited, cycle_last);
if (!inited) {
inited = true;
cycle_last = s->tc.cycle_last;
}
}
i++;
}
snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
@ -726,14 +724,13 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
unsigned int streams)
{
struct hdac_bus *bus = azx_dev->bus;
int i, nwait, timeout;
int nwait, timeout;
struct hdac_stream *s;
for (timeout = 5000; timeout; timeout--) {
nwait = 0;
i = 0;
list_for_each_entry(s, &bus->stream_list, list) {
if (!(streams & (1 << i++)))
if (!(streams & (1 << s->index)))
continue;
if (start) {

View File

@ -521,6 +521,16 @@ static const struct config_entry config_table[] = {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = PCI_DEVICE_ID_INTEL_HDA_MTL,
},
/* ArrowLake-S */
{
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = PCI_DEVICE_ID_INTEL_HDA_ARL_S,
},
/* ArrowLake */
{
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = PCI_DEVICE_ID_INTEL_HDA_ARL,
},
#endif
/* Lunar Lake */

View File

@ -191,9 +191,9 @@ snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
"> 512 bytes to FX\n");
return -EIO;
}
page_data = memdup_user((unsigned char __user *)
r.data[3],
r.data[2] * sizeof(short));
page_data = memdup_array_user((unsigned char __user *)
r.data[3],
r.data[2], sizeof(short));
if (IS_ERR(page_data))
return PTR_ERR(page_data);
pd = page_data;

View File

@ -10,7 +10,7 @@
* Thanks to the ALSA developers, they helped a lot working out
* the ALSA part.
* Thanks also to Sourceforge for maintaining the old binary drivers,
* and the forum, where developers could comunicate.
* and the forum, where developers could communicate.
*
* Now at least i can play Legacy DOOM with MIDI music :-)
*/

View File

@ -1195,7 +1195,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
/* Force write through cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
(((adbdma << 2) + pp) << 2));
}
@ -1237,7 +1237,7 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
/* Force write through cache. */
hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
}
}
@ -1466,7 +1466,7 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
(((wtdma << 2) + pp) << 2),
snd_pcm_sgbuf_get_addr(dma->substream,
dma->period_bytes * p));
/* Force write thru cache. */
/* Force write through cache. */
hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
(((wtdma << 2) + pp) << 2));
}
@ -1854,7 +1854,7 @@ vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
vortex_mix_disableinput(vortex, mix, mixin, a);
}
// Connect absolut address to mixin.
// Connect absolute address to mixin.
static void
vortex_connection_adb_mixin(vortex_t * vortex, int en,
unsigned char channel, unsigned char source,
@ -1880,7 +1880,7 @@ vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
ADB_DMA(adbdma));
}
// mix to absolut address.
// mix to absolute address.
static void
vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
unsigned char mix, unsigned char dest)

View File

@ -12,6 +12,7 @@
#include <sound/hda_codec.h>
#include <sound/soc.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
#include "hda_local.h"
#include "hda_auto_parser.h"
#include "hda_jack.h"
@ -996,6 +997,11 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41)
__be32 halo_sts;
int ret;
if (cs35l41->bypass_fw) {
dev_warn(cs35l41->dev, "Bypassing Firmware.\n");
return 0;
}
ret = cs35l41_init_dsp(cs35l41);
if (ret) {
dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret);
@ -1588,6 +1594,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
u32 values[HDA_MAX_COMPONENTS];
struct acpi_device *adev;
struct device *physdev;
struct spi_device *spi;
const char *sub;
char *property;
size_t nval;
@ -1610,7 +1617,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
if (!ret) {
dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
goto put_physdev;
goto out;
}
property = "cirrus,dev-index";
@ -1701,8 +1708,20 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
hw_cfg->bst_type = CS35L41_EXT_BOOST;
hw_cfg->valid = true;
out:
put_device(physdev);
cs35l41->bypass_fw = false;
if (cs35l41->control_bus == SPI) {
spi = to_spi_device(cs35l41->dev);
if (spi->max_speed_hz < CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ) {
dev_warn(cs35l41->dev,
"SPI speed is too slow to support firmware download: %d Hz.\n",
spi->max_speed_hz);
cs35l41->bypass_fw = true;
}
}
return 0;
err:
@ -1711,14 +1730,13 @@ err:
hw_cfg->gpio1.valid = false;
hw_cfg->gpio2.valid = false;
acpi_dev_put(cs35l41->dacpi);
put_physdev:
put_device(physdev);
return ret;
}
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
struct regmap *regmap)
struct regmap *regmap, enum control_bus control_bus)
{
unsigned int regid, reg_revid;
struct cs35l41_hda *cs35l41;
@ -1737,6 +1755,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
cs35l41->dev = dev;
cs35l41->irq = irq;
cs35l41->regmap = regmap;
cs35l41->control_bus = control_bus;
dev_set_drvdata(dev, cs35l41);
ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);

View File

@ -20,6 +20,8 @@
#include <linux/firmware/cirrus/cs_dsp.h>
#include <linux/firmware/cirrus/wmfw.h>
#define CS35L41_MAX_ACCEPTABLE_SPI_SPEED_HZ 1000000
struct cs35l41_amp_cal_data {
u32 calTarget[2];
u32 calTime[2];
@ -46,6 +48,11 @@ enum cs35l41_hda_gpio_function {
CS35l41_SYNC,
};
enum control_bus {
I2C,
SPI
};
struct cs35l41_hda {
struct device *dev;
struct regmap *regmap;
@ -74,6 +81,9 @@ struct cs35l41_hda {
struct cs_dsp cs_dsp;
struct acpi_device *dacpi;
bool mute_override;
enum control_bus control_bus;
bool bypass_fw;
};
enum halo_state {
@ -85,7 +95,7 @@ enum halo_state {
extern const struct dev_pm_ops cs35l41_hda_pm_ops;
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
struct regmap *regmap);
struct regmap *regmap, enum control_bus control_bus);
void cs35l41_hda_remove(struct device *dev);
int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id);

View File

@ -30,7 +30,7 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt)
return -ENODEV;
return cs35l41_hda_probe(&clt->dev, device_name, clt->addr, clt->irq,
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c));
devm_regmap_init_i2c(clt, &cs35l41_regmap_i2c), I2C);
}
static void cs35l41_hda_i2c_remove(struct i2c_client *clt)

View File

@ -16,10 +16,6 @@
struct cs35l41_config {
const char *ssid;
enum {
SPI,
I2C
} bus;
int num_amps;
enum {
INTERNAL,
@ -35,42 +31,72 @@ struct cs35l41_config {
};
static const struct cs35l41_config cs35l41_config_table[] = {
{ "10280B27", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10280B28", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10280BEB", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10280C4D", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 1, -1, 1000, 4500, 24 },
/*
* Device 103C89C6 does have _DSD, however it is setup to use the wrong boost type.
* We can override the _DSD to correct the boost type here.
* Since this laptop has valid ACPI, we do not need to handle cs-gpios, since that already exists
* in the ACPI. The Reset GPIO is also valid, so we can use the Reset defined in _DSD.
*/
{ "103C89C6", SPI, 2, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, -1, -1, -1, 1000, 4500, 24 },
{ "104312AF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431433", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431463", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431473", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "10431483", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "10431493", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104314D3", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104314E3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431503", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431533", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431573", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431663", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "104316D3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104316F3", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104317F3", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431863", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104318D3", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "10431C9F", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CAF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CCF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CDF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CEF", SPI, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431D1F", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431DA2", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10431E02", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10431EE2", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "103C89C6", 2, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, -1, -1, -1, 1000, 4500, 24 },
{ "103C8A28", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A29", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A2A", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A2B", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A2C", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A2D", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A2E", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A30", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8A31", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BB3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BB4", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BDF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE0", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE1", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE2", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE9", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BDD", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BDE", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE5", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8BE6", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "103C8B3A", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4100, 24 },
{ "104312AF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431433", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431463", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431473", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "10431483", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "10431493", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104314D3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104314E3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431503", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431533", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431573", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431663", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "104316D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104316F3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104317F3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431863", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "104318D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "10431C9F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CAF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CCF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CDF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431CEF", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431D1F", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431DA2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10431E02", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "10431EE2", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, -1, -1, 0, 0, 0 },
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA38B7", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{}
};
@ -208,7 +234,7 @@ static int generic_dsd_config(struct cs35l41_hda *cs35l41, struct device *physde
"_DSD already exists.\n");
}
if (cfg->bus == SPI) {
if (cs35l41->control_bus == SPI) {
cs35l41->index = id;
/*
@ -345,7 +371,33 @@ struct cs35l41_prop_model {
static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
{ "CSC3551", "10280B27", generic_dsd_config },
{ "CSC3551", "10280B28", generic_dsd_config },
{ "CSC3551", "10280BEB", generic_dsd_config },
{ "CSC3551", "10280C4D", generic_dsd_config },
{ "CSC3551", "103C89C6", generic_dsd_config },
{ "CSC3551", "103C8A28", generic_dsd_config },
{ "CSC3551", "103C8A29", generic_dsd_config },
{ "CSC3551", "103C8A2A", generic_dsd_config },
{ "CSC3551", "103C8A2B", generic_dsd_config },
{ "CSC3551", "103C8A2C", generic_dsd_config },
{ "CSC3551", "103C8A2D", generic_dsd_config },
{ "CSC3551", "103C8A2E", generic_dsd_config },
{ "CSC3551", "103C8A30", generic_dsd_config },
{ "CSC3551", "103C8A31", generic_dsd_config },
{ "CSC3551", "103C8BB3", generic_dsd_config },
{ "CSC3551", "103C8BB4", generic_dsd_config },
{ "CSC3551", "103C8BDF", generic_dsd_config },
{ "CSC3551", "103C8BE0", generic_dsd_config },
{ "CSC3551", "103C8BE1", generic_dsd_config },
{ "CSC3551", "103C8BE2", generic_dsd_config },
{ "CSC3551", "103C8BE9", generic_dsd_config },
{ "CSC3551", "103C8BDD", generic_dsd_config },
{ "CSC3551", "103C8BDE", generic_dsd_config },
{ "CSC3551", "103C8BE3", generic_dsd_config },
{ "CSC3551", "103C8BE5", generic_dsd_config },
{ "CSC3551", "103C8BE6", generic_dsd_config },
{ "CSC3551", "103C8B3A", generic_dsd_config },
{ "CSC3551", "104312AF", generic_dsd_config },
{ "CSC3551", "10431433", generic_dsd_config },
{ "CSC3551", "10431463", generic_dsd_config },
@ -375,6 +427,10 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F12", generic_dsd_config },
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
{ "CSC3551", "17AA38B4", generic_dsd_config },
{ "CSC3551", "17AA38B5", generic_dsd_config },
{ "CSC3551", "17AA38B6", generic_dsd_config },
{ "CSC3551", "17AA38B7", generic_dsd_config },
{}
};

View File

@ -26,7 +26,7 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi)
return -ENODEV;
return cs35l41_hda_probe(&spi->dev, device_name, spi_get_chipselect(spi, 0), spi->irq,
devm_regmap_init_spi(spi, &cs35l41_regmap_spi));
devm_regmap_init_spi(spi, &cs35l41_regmap_spi), SPI);
}
static void cs35l41_hda_spi_remove(struct spi_device *spi)

View File

@ -3163,6 +3163,7 @@ static int set_pcm_default_values(struct hda_codec *codec,
err = snd_hda_query_supported_pcm(codec, info->nid,
info->rates ? NULL : &info->rates,
info->formats ? NULL : &info->formats,
info->subformats ? NULL : &info->subformats,
info->maxbps ? NULL : &info->maxbps);
if (err < 0)
return err;
@ -3757,6 +3758,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
&mout->spdif_rates,
&mout->spdif_formats,
NULL,
&mout->spdif_maxbps);
}
mutex_lock(&codec->spdif_mutex);

View File

@ -151,7 +151,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
struct azx_dev *azx_dev = get_azx_dev(substream);
struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int format_val, stream_tag;
unsigned int format_val, stream_tag, bits;
int err;
struct hda_spdif_out *spdif =
snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
@ -165,11 +165,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
}
snd_hdac_stream_reset(azx_stream(azx_dev));
format_val = snd_hdac_calc_stream_format(runtime->rate,
runtime->channels,
runtime->format,
hinfo->maxbps,
ctls);
bits = snd_hdac_stream_format_bits(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps);
format_val = snd_hdac_spdif_stream_format(runtime->channels, bits, runtime->rate, ctls);
if (!format_val) {
dev_err(chip->card->dev,
"invalid format_val, rate=%d, ch=%d, format=%d\n",

View File

@ -2504,6 +2504,8 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
/* Arrow Lake-S */
{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
/* Arrow Lake */
{ PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
/* Apollolake (Broxton-P) */
{ PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
/* Gemini-Lake */

View File

@ -3022,8 +3022,7 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
{
unsigned int format_val;
format_val = snd_hdac_calc_stream_format(sample_rate,
channels, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
format_val = snd_hdac_stream_format(channels, 32, sample_rate);
if (hda_format)
*hda_format = (unsigned short)format_val;

View File

@ -1655,7 +1655,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
#define I915_SILENT_RATE 48000
#define I915_SILENT_CHANNELS 2
#define I915_SILENT_FORMAT SNDRV_PCM_FORMAT_S16_LE
#define I915_SILENT_FORMAT_BITS 16
#define I915_SILENT_FMT_MASK 0xf
@ -1668,8 +1667,8 @@ static void silent_stream_enable_i915(struct hda_codec *codec,
per_pin->dev_id, I915_SILENT_RATE);
/* trigger silent stream generation in hw */
format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
format = snd_hdac_stream_format(I915_SILENT_CHANNELS, I915_SILENT_FORMAT_BITS,
I915_SILENT_RATE);
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
usleep_range(100, 200);
@ -1977,6 +1976,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
err = snd_hda_query_supported_pcm(codec, cvt_nid,
&per_cvt->rates,
&per_cvt->formats,
NULL,
&per_cvt->maxbps);
if (err < 0)
return err;

View File

@ -6956,6 +6956,11 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
}
static void cs35l41_fixup_i2c_four(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
{
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 4);
}
static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
{
cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 2);
@ -6984,6 +6989,12 @@ static void tas2781_fixup_i2c(struct hda_codec *cdc,
tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
}
static void yoga7_14arb7_fixup_i2c(struct hda_codec *cdc,
const struct hda_fixup *fix, int action)
{
tas2781_generic_fixup(cdc, action, "i2c", "INT8866");
}
/* for alc295_fixup_hp_top_speakers */
#include "hp_x360_helper.c"
@ -7441,6 +7452,7 @@ enum {
ALC287_FIXUP_LEGION_16ACHG6,
ALC287_FIXUP_CS35L41_I2C_2,
ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
ALC287_FIXUP_CS35L41_I2C_4,
ALC245_FIXUP_CS35L41_SPI_2,
ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
ALC245_FIXUP_CS35L41_SPI_4,
@ -7454,6 +7466,7 @@ enum {
ALC236_FIXUP_DELL_DUAL_CODECS,
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
ALC287_FIXUP_TAS2781_I2C,
ALC287_FIXUP_YOGA7_14ARB7_I2C,
ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
ALC245_FIXUP_HP_X360_MUTE_LEDS,
ALC287_FIXUP_THINKPAD_I2S_SPK,
@ -9427,6 +9440,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC285_FIXUP_HP_MUTE_LED,
},
[ALC287_FIXUP_CS35L41_I2C_4] = {
.type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_i2c_four,
},
[ALC245_FIXUP_CS35L41_SPI_2] = {
.type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_spi_two,
@ -9568,6 +9585,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
},
[ALC287_FIXUP_YOGA7_14ARB7_I2C] = {
.type = HDA_FIXUP_FUNC,
.v.func = yoga7_14arb7_fixup_i2c,
.chained = true,
.chain_id = ALC285_FIXUP_THINKPAD_HEADSET_JACK,
},
[ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc245_fixup_hp_mute_led_coefbit,
@ -9703,6 +9726,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0b27, "Dell", ALC245_FIXUP_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0b28, "Dell", ALC245_FIXUP_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2),
@ -9713,6 +9738,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c4d, "Dell", ALC287_FIXUP_CS35L41_I2C_4),
SND_PCI_QUIRK(0x1028, 0x0cbd, "Dell Oasis 13 CS MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0cbe, "Dell Oasis 13 2-IN-1 MTL-U", ALC289_FIXUP_DELL_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0cbf, "Dell Oasis 13 Low Weight MTU-L", ALC289_FIXUP_DELL_CS35L41_SPI_2),
@ -10221,6 +10247,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
@ -10229,6 +10256,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38b4, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b7, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),

View File

@ -65,6 +65,24 @@ enum calib_data {
CALIB_MAX
};
#define TAS2563_MAX_CHANNELS 4
#define TAS2563_CAL_POWER TASDEVICE_REG(0, 0x0d, 0x3c)
#define TAS2563_CAL_R0 TASDEVICE_REG(0, 0x0f, 0x34)
#define TAS2563_CAL_INVR0 TASDEVICE_REG(0, 0x0f, 0x40)
#define TAS2563_CAL_R0_LOW TASDEVICE_REG(0, 0x0f, 0x48)
#define TAS2563_CAL_TLIM TASDEVICE_REG(0, 0x10, 0x14)
#define TAS2563_CAL_N 5
#define TAS2563_CAL_DATA_SIZE 4
#define TAS2563_CAL_CH_SIZE 20
#define TAS2563_CAL_ARRAY_SIZE 80
static unsigned int cal_regs[TAS2563_CAL_N] = {
TAS2563_CAL_POWER, TAS2563_CAL_R0, TAS2563_CAL_INVR0,
TAS2563_CAL_R0_LOW, TAS2563_CAL_TLIM,
};
struct tas2781_hda {
struct device *dev;
struct tasdevice_priv *priv;
@ -81,7 +99,7 @@ static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
if (i2c_acpi_get_i2c_resource(ares, &sb)) {
if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&
sb->slave_address != TAS2781_GLOBAL_ADDR) {
sb->slave_address != tas_priv->global_addr) {
tas_priv->tasdevice[tas_priv->ndev].dev_addr =
(unsigned int)sb->slave_address;
tas_priv->ndev++;
@ -404,6 +422,69 @@ static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = {
.put = tasdevice_config_put,
};
static void tas2563_apply_calib(struct tasdevice_priv *tas_priv)
{
unsigned int data;
int offset = 0;
int ret;
for (int i = 0; i < tas_priv->ndev; i++) {
for (int j = 0; j < TAS2563_CAL_N; ++j) {
data = cpu_to_be32(
*(uint32_t *)&tas_priv->cali_data.data[offset]);
ret = tasdevice_dev_bulk_write(tas_priv, i, cal_regs[j],
(unsigned char *)&data, TAS2563_CAL_DATA_SIZE);
if (ret)
dev_err(tas_priv->dev,
"Error writing calib regs\n");
offset += TAS2563_CAL_DATA_SIZE;
}
}
}
static int tas2563_save_calibration(struct tasdevice_priv *tas_priv)
{
static efi_guid_t efi_guid = EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc,
0x09, 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92);
static efi_char16_t *efi_vars[TAS2563_MAX_CHANNELS][TAS2563_CAL_N] = {
{ L"Power_1", L"R0_1", L"InvR0_1", L"R0_Low_1", L"TLim_1" },
{ L"Power_2", L"R0_2", L"InvR0_2", L"R0_Low_2", L"TLim_2" },
{ L"Power_3", L"R0_3", L"InvR0_3", L"R0_Low_3", L"TLim_3" },
{ L"Power_4", L"R0_4", L"InvR0_4", L"R0_Low_4", L"TLim_4" },
};
unsigned long max_size = TAS2563_CAL_DATA_SIZE;
unsigned int offset = 0;
efi_status_t status;
unsigned int attr;
tas_priv->cali_data.data = devm_kzalloc(tas_priv->dev,
TAS2563_CAL_ARRAY_SIZE, GFP_KERNEL);
if (!tas_priv->cali_data.data)
return -ENOMEM;
for (int i = 0; i < tas_priv->ndev; ++i) {
for (int j = 0; j < TAS2563_CAL_N; ++j) {
status = efi.get_variable(efi_vars[i][j],
&efi_guid, &attr, &max_size,
&tas_priv->cali_data.data[offset]);
if (status != EFI_SUCCESS ||
max_size != TAS2563_CAL_DATA_SIZE) {
dev_warn(tas_priv->dev,
"Calibration data read failed %ld\n", status);
return -EINVAL;
}
offset += TAS2563_CAL_DATA_SIZE;
}
}
tas_priv->cali_data.total_sz = offset;
tasdevice_apply_calibration(tas_priv);
return 0;
}
static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
{
static const unsigned char page_array[CALIB_MAX] = {
@ -479,7 +560,7 @@ static int tas2781_save_calibration(struct tasdevice_priv *tas_priv)
dev_dbg(tas_priv->dev, "%4ld-%2d-%2d, %2d:%2d:%2d\n",
tm->tm_year, tm->tm_mon, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
tas2781_apply_calib(tas_priv);
tasdevice_apply_calibration(tas_priv);
} else
tas_priv->cali_data.total_sz = 0;
@ -582,7 +663,9 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
/* If calibrated data occurs error, dsp will still works with default
* calibrated data inside algo.
*/
tas2781_save_calibration(tas_priv);
tasdevice_save_calibration(tas_priv);
tasdevice_tuning_switch(tas_hda->priv, 0);
out:
mutex_unlock(&tas_hda->priv->codec_lock);
@ -683,10 +766,6 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
const char *device_name;
int ret;
if (strstr(dev_name(&clt->dev), "TIAS2781"))
device_name = "TIAS2781";
else
return -ENODEV;
tas_hda = devm_kzalloc(&clt->dev, sizeof(*tas_hda), GFP_KERNEL);
if (!tas_hda)
@ -699,6 +778,19 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
if (!tas_hda->priv)
return -ENOMEM;
if (strstr(dev_name(&clt->dev), "TIAS2781")) {
device_name = "TIAS2781";
tas_hda->priv->save_calibration = tas2781_save_calibration;
tas_hda->priv->apply_calibration = tas2781_apply_calib;
tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;
} else if (strstr(dev_name(&clt->dev), "INT8866")) {
device_name = "INT8866";
tas_hda->priv->save_calibration = tas2563_save_calibration;
tas_hda->priv->apply_calibration = tas2563_apply_calib;
tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;
} else
return -ENODEV;
tas_hda->priv->irq_info.irq = clt->irq;
ret = tas2781_read_acpi(tas_hda->priv, device_name);
if (ret)
@ -765,8 +857,6 @@ static int tas2781_runtime_suspend(struct device *dev)
static int tas2781_runtime_resume(struct device *dev)
{
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
unsigned long calib_data_sz =
tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
dev_dbg(tas_hda->dev, "Runtime Resume\n");
@ -777,8 +867,7 @@ static int tas2781_runtime_resume(struct device *dev)
/* If calibrated data occurs error, dsp will still works with default
* calibrated data inside algo.
*/
if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
tas2781_apply_calib(tas_hda->priv);
tasdevice_apply_calibration(tas_hda->priv);
mutex_unlock(&tas_hda->priv->codec_lock);
@ -809,8 +898,6 @@ static int tas2781_system_suspend(struct device *dev)
static int tas2781_system_resume(struct device *dev)
{
struct tas2781_hda *tas_hda = dev_get_drvdata(dev);
unsigned long calib_data_sz =
tas_hda->priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
int i, ret;
dev_info(tas_hda->priv->dev, "System Resume\n");
@ -832,8 +919,7 @@ static int tas2781_system_resume(struct device *dev)
/* If calibrated data occurs error, dsp will still work with default
* calibrated data inside algo.
*/
if (tas_hda->priv->cali_data.total_sz > calib_data_sz)
tas2781_apply_calib(tas_hda->priv);
tasdevice_apply_calibration(tas_hda->priv);
mutex_unlock(&tas_hda->priv->codec_lock);
return 0;
@ -851,6 +937,7 @@ static const struct i2c_device_id tas2781_hda_i2c_id[] = {
static const struct acpi_device_id tas2781_acpi_hda_match[] = {
{"TIAS2781", 0 },
{"INT8866", 0 },
{}
};
MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);

View File

@ -76,13 +76,16 @@ static int hda_codec_dai_prepare(struct snd_pcm_substream *substream, struct snd
struct hdac_stream *stream;
struct hda_codec *codec;
unsigned int format;
unsigned int bits;
int ret;
codec = dev_to_hda_codec(dai->dev);
stream = substream->runtime->private_data;
stream_info = snd_soc_dai_get_dma_data(dai, substream);
format = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
runtime->sample_bits, 0);
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
stream_info->maxbps);
format = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
ret = snd_hda_codec_prepare(codec, stream_info, stream->stream_tag, format, substream);
if (ret < 0) {

View File

@ -52,6 +52,7 @@ static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count,
stream->channels_max = pcm->stream[dir].channels_max;
stream->rates = pcm->stream[dir].rates;
stream->formats = pcm->stream[dir].formats;
stream->subformats = pcm->stream[dir].subformats;
stream->sig_bits = pcm->stream[dir].maxbps;
capture_dais:
@ -71,6 +72,7 @@ capture_dais:
stream->channels_max = pcm->stream[dir].channels_max;
stream->rates = pcm->stream[dir].rates;
stream->formats = pcm->stream[dir].formats;
stream->subformats = pcm->stream[dir].subformats;
stream->sig_bits = pcm->stream[dir].maxbps;
}

View File

@ -218,18 +218,16 @@ static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,
struct hdac_hda_priv *hda_pvt;
unsigned int format_val;
unsigned int maxbps;
unsigned int bits;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
maxbps = dai->driver->playback.sig_bits;
else
maxbps = dai->driver->capture.sig_bits;
bits = snd_hdac_stream_format_bits(params_format(params), SNDRV_PCM_SUBFORMAT_STD, maxbps);
hda_pvt = snd_soc_component_get_drvdata(component);
format_val = snd_hdac_calc_stream_format(params_rate(params),
params_channels(params),
params_format(params),
maxbps,
0);
format_val = snd_hdac_stream_format(params_channels(params), bits, params_rate(params));
if (!format_val) {
dev_err(dai->dev,
"invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n",

View File

@ -468,13 +468,14 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_pcm *pcm;
unsigned int bits;
int format;
dai_map = &hdmi->dai_map[dai->id];
format = snd_hdac_calc_stream_format(params_rate(hparams),
params_channels(hparams), params_format(hparams),
dai->driver->playback.sig_bits, 0);
bits = snd_hdac_stream_format_bits(params_format(hparams), SNDRV_PCM_SUBFORMAT_STD,
dai->driver->playback.sig_bits);
format = snd_hdac_stream_format(params_channels(hparams), bits, params_rate(hparams));
pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
if (!pcm)
@ -670,6 +671,7 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)
err = snd_hdac_query_supported_pcm(hdev, cvt->nid,
&cvt->params.rates,
&cvt->params.formats,
NULL,
&cvt->params.maxbps);
if (err < 0)
dev_err(&hdev->dev,
@ -1577,7 +1579,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdev,
list_for_each_entry(cvt, &hdmi->cvt_list, head) {
ret = snd_hdac_query_supported_pcm(hdev, cvt->nid,
&rates, &formats, &bps);
&rates, &formats, NULL, &bps);
if (ret)
return ret;

View File

@ -412,6 +412,21 @@ void tasdevice_remove(struct tasdevice_priv *tas_priv)
}
EXPORT_SYMBOL_GPL(tasdevice_remove);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv)
{
if (tas_priv->save_calibration)
return tas_priv->save_calibration(tas_priv);
return -EINVAL;
}
EXPORT_SYMBOL_GPL(tasdevice_save_calibration);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv)
{
if (tas_priv->apply_calibration && tas_priv->cali_data.total_sz)
tas_priv->apply_calibration(tas_priv);
}
EXPORT_SYMBOL_GPL(tasdevice_apply_calibration);
static int tasdevice_clamp(int val, int max, unsigned int invert)
{
if (val > max)

View File

@ -371,7 +371,7 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw)
hstream = hdac_stream(estream);
/* code loading performed with default format */
sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
sdfmt = snd_hdac_stream_format(1, 32, 48000);
ret = snd_hdac_dsp_prepare(hstream, sdfmt, fw->size, &dmab);
if (ret < 0)
goto release_stream;
@ -438,7 +438,7 @@ int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id)
stream = hdac_stream(estream);
/* code loading performed with default format */
sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
sdfmt = snd_hdac_stream_format(1, 32, 48000);
ret = snd_hdac_dsp_prepare(stream, sdfmt, lib->size, &dmab);
if (ret < 0)
goto release_stream;

View File

@ -87,7 +87,7 @@ static bool avs_test_hw_params(struct snd_pcm_hw_params *params,
return (params_rate(params) == fmt->sampling_freq &&
params_channels(params) == fmt->num_channels &&
params_physical_width(params) == fmt->bit_depth &&
params_width(params) == fmt->valid_bit_depth);
snd_pcm_hw_params_bits(params) == fmt->valid_bit_depth);
}
static struct avs_tplg_path *

View File

@ -17,6 +17,7 @@
#include "avs.h"
#include "path.h"
#include "topology.h"
#include "../../codecs/hda.h"
struct avs_dma_data {
struct avs_tplg_path_template *template;
@ -335,20 +336,25 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct hdac_ext_stream *link_stream = runtime->private_data;
struct snd_soc_pcm_stream *stream_info;
struct hdac_ext_stream *link_stream;
struct hdac_ext_link *link;
struct hda_codec *codec;
struct hdac_bus *bus;
unsigned int format_val;
unsigned int bits;
int ret;
link_stream = runtime->private_data;
if (link_stream->link_prepared)
return 0;
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
bus = &codec->bus->core;
format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
runtime->sample_bits, 0);
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
stream_info->sig_bits);
format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
snd_hdac_ext_stream_reset(link_stream);
snd_hdac_ext_stream_setup(link_stream, format_val);
@ -600,10 +606,12 @@ static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_so
static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_stream *stream_info;
struct avs_dma_data *data;
struct avs_dev *adev = to_avs_dev(dai->dev);
struct hdac_ext_stream *host_stream;
unsigned int format_val;
unsigned int bits;
int ret;
data = snd_soc_dai_get_dma_data(dai, substream);
@ -614,8 +622,10 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
snd_hdac_stream_reset(hdac_stream(host_stream));
format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
runtime->sample_bits, 0);
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
stream_info->sig_bits);
format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
if (ret < 0)
@ -1064,8 +1074,10 @@ static const struct snd_pcm_hardware avs_pcm_hardware = {
SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
.buffer_bytes_max = AZX_MAX_BUF_SIZE,
.period_bytes_min = 128,
.period_bytes_max = AZX_MAX_BUF_SIZE / 2,
@ -1216,8 +1228,10 @@ static const struct snd_soc_dai_driver i2s_dai_template = {
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
},
.capture = {
.channels_min = 1,
@ -1225,8 +1239,10 @@ static const struct snd_soc_dai_driver i2s_dai_template = {
.rates = SNDRV_PCM_RATE_8000_192000 |
SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
},
};
@ -1301,16 +1317,20 @@ static const struct snd_soc_dai_driver hda_cpu_dai = {
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
},
.capture = {
.channels_min = 1,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
},
};
@ -1387,6 +1407,15 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
ret = -ENOMEM;
goto exit;
}
if (!hda_codec_is_display(codec)) {
dais[i].playback.formats = pcm->stream[0].formats;
dais[i].playback.subformats = pcm->stream[0].subformats;
dais[i].playback.rates = pcm->stream[0].rates;
dais[i].playback.channels_min = pcm->stream[0].channels_min;
dais[i].playback.channels_max = pcm->stream[0].channels_max;
dais[i].playback.sig_bits = pcm->stream[0].maxbps;
}
}
if (pcm->stream[1].substreams) {
@ -1397,6 +1426,15 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
ret = -ENOMEM;
goto exit;
}
if (!hda_codec_is_display(codec)) {
dais[i].capture.formats = pcm->stream[1].formats;
dais[i].capture.subformats = pcm->stream[1].subformats;
dais[i].capture.rates = pcm->stream[1].rates;
dais[i].capture.channels_min = pcm->stream[1].channels_min;
dais[i].capture.channels_max = pcm->stream[1].channels_max;
dais[i].capture.sig_bits = pcm->stream[1].maxbps;
}
}
dai = snd_soc_register_dai(component, &dais[i], false);

View File

@ -140,8 +140,7 @@ static int avs_probe_compr_set_params(struct snd_compr_stream *cstream,
bps = snd_pcm_format_physical_width(format);
if (bps < 0)
return bps;
format_val = snd_hdac_calc_stream_format(params->codec.sample_rate, params->codec.ch_out,
format, bps, 0);
format_val = snd_hdac_stream_format(params->codec.ch_out, bps, params->codec.sample_rate);
ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
if (ret < 0)
return ret;

View File

@ -1514,8 +1514,16 @@ static int avs_dai_load(struct snd_soc_component *comp, int index,
struct snd_soc_dai_driver *dai_drv, struct snd_soc_tplg_pcm *pcm,
struct snd_soc_dai *dai)
{
if (pcm)
u32 fe_subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX;
if (pcm) {
dai_drv->ops = &avs_dai_fe_ops;
dai_drv->capture.subformats = fe_subformats;
dai_drv->playback.subformats = fe_subformats;
}
return 0;
}
@ -1534,6 +1542,9 @@ static int avs_link_load(struct snd_soc_component *comp, int index, struct snd_s
/* Open LINK (BE) pipes last and close them first to prevent xruns. */
link->trigger[0] = SND_SOC_DPCM_TRIGGER_PRE;
link->trigger[1] = SND_SOC_DPCM_TRIGGER_PRE;
} else {
/* Do not ignore codec capabilities. */
link->dpcm_merged_format = 1;
}
return 0;

View File

@ -127,6 +127,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
unsigned int format_val;
struct hdac_stream *hstream;
struct hdac_ext_stream *stream;
unsigned int bits;
int err;
hstream = snd_hdac_get_stream(bus, params->stream,
@ -137,8 +138,9 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
stream = stream_to_hdac_ext_stream(hstream);
snd_hdac_ext_stream_decouple(bus, stream, true);
format_val = snd_hdac_calc_stream_format(params->s_freq,
params->ch, params->format, params->host_bps, 0);
bits = snd_hdac_stream_format_bits(params->format, SNDRV_PCM_SUBFORMAT_STD,
params->host_bps);
format_val = snd_hdac_stream_format(params->ch, bits, params->s_freq);
dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
format_val, params->s_freq, params->ch, params->format);
@ -165,6 +167,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
struct hdac_ext_stream *stream;
struct hdac_ext_link *link;
unsigned char stream_tag;
unsigned int bits;
hstream = snd_hdac_get_stream(bus, params->stream,
params->link_dma_id + 1);
@ -173,8 +176,10 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
stream = stream_to_hdac_ext_stream(hstream);
snd_hdac_ext_stream_decouple(bus, stream, true);
format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
params->format, params->link_bps, 0);
bits = snd_hdac_stream_format_bits(params->format, SNDRV_PCM_SUBFORMAT_STD,
params->link_bps);
format_val = snd_hdac_stream_format(params->ch, bits, params->s_freq);
dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
format_val, params->s_freq, params->ch, params->format);

View File

@ -554,6 +554,12 @@ static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw,
hw->formats &= p->formats;
}
static void soc_pcm_hw_update_subformat(struct snd_pcm_hardware *hw,
struct snd_soc_pcm_stream *p)
{
hw->subformats &= p->subformats;
}
/**
* snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream
* @rtd: ASoC PCM runtime
@ -592,6 +598,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
soc_pcm_hw_update_chan(hw, cpu_stream);
soc_pcm_hw_update_rate(hw, cpu_stream);
soc_pcm_hw_update_format(hw, cpu_stream);
soc_pcm_hw_update_subformat(hw, cpu_stream);
}
cpu_chan_min = hw->channels_min;
cpu_chan_max = hw->channels_max;
@ -613,6 +620,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
soc_pcm_hw_update_chan(hw, codec_stream);
soc_pcm_hw_update_rate(hw, codec_stream);
soc_pcm_hw_update_format(hw, codec_stream);
soc_pcm_hw_update_subformat(hw, codec_stream);
}
/* Verify both a valid CPU DAI and a valid CODEC DAI were found */
@ -1710,6 +1718,7 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
soc_pcm_hw_update_rate(hw, cpu_stream);
soc_pcm_hw_update_chan(hw, cpu_stream);
soc_pcm_hw_update_format(hw, cpu_stream);
soc_pcm_hw_update_subformat(hw, cpu_stream);
}
}
@ -1747,6 +1756,7 @@ static void dpcm_runtime_setup_be_format(struct snd_pcm_substream *substream)
codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
soc_pcm_hw_update_format(hw, codec_stream);
soc_pcm_hw_update_subformat(hw, codec_stream);
}
}
}

View File

@ -208,14 +208,16 @@ static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev,
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
unsigned int link_bps;
unsigned int format_val;
unsigned int bits;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
link_bps = codec_dai->driver->playback.sig_bits;
else
link_bps = codec_dai->driver->capture.sig_bits;
format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
params_format(params), link_bps, 0);
bits = snd_hdac_stream_format_bits(params_format(params), SNDRV_PCM_SUBFORMAT_STD,
link_bps);
format_val = snd_hdac_stream_format(params_channels(params), bits, params_rate(params));
dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
params_rate(params), params_channels(params), params_format(params));
@ -238,11 +240,11 @@ static unsigned int generic_calc_stream_format(struct snd_sof_dev *sdev,
struct snd_pcm_hw_params *params)
{
unsigned int format_val;
unsigned int bits;
format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
params_format(params),
params_physical_width(params),
0);
bits = snd_hdac_stream_format_bits(params_format(params), SNDRV_PCM_SUBFORMAT_STD,
params_physical_width(params));
format_val = snd_hdac_stream_format(params_channels(params), bits, params_rate(params));
dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
params_rate(params), params_channels(params), params_format(params));
@ -258,6 +260,7 @@ static unsigned int dmic_calc_stream_format(struct snd_sof_dev *sdev,
snd_pcm_format_t format;
unsigned int channels;
unsigned int width;
unsigned int bits;
channels = params_channels(params);
format = params_format(params);
@ -269,10 +272,8 @@ static unsigned int dmic_calc_stream_format(struct snd_sof_dev *sdev,
width = 32;
}
format_val = snd_hdac_calc_stream_format(params_rate(params), channels,
format,
width,
0);
bits = snd_hdac_stream_format_bits(format, SNDRV_PCM_SUBFORMAT_STD, width);
format_val = snd_hdac_stream_format(channels, bits, params_rate(params));
dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
params_rate(params), channels, format);

View File

@ -882,6 +882,7 @@ extern const struct sof_intel_dsp_desc ehl_chip_info;
extern const struct sof_intel_dsp_desc jsl_chip_info;
extern const struct sof_intel_dsp_desc adls_chip_info;
extern const struct sof_intel_dsp_desc mtl_chip_info;
extern const struct sof_intel_dsp_desc arl_s_chip_info;
extern const struct sof_intel_dsp_desc lnl_chip_info;
/* Probes support */

View File

@ -746,3 +746,31 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
.hw_ip_version = SOF_INTEL_ACE_1_0,
};
EXPORT_SYMBOL_NS(mtl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
const struct sof_intel_dsp_desc arl_s_chip_info = {
.cores_num = 2,
.init_core_mask = BIT(0),
.host_managed_cores_mask = BIT(0),
.ipc_req = MTL_DSP_REG_HFIPCXIDR,
.ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
.ipc_ack = MTL_DSP_REG_HFIPCXIDA,
.ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
.ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
.rom_status_reg = MTL_DSP_ROM_STS,
.rom_init_timeout = 300,
.ssp_count = MTL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE_ACE,
.sdw_alh_base = SDW_ALH_BASE_ACE,
.d0i3_offset = MTL_HDA_VS_D0I3C,
.read_sdw_lcount = hda_sdw_check_lcount_common,
.enable_sdw_irq = mtl_enable_sdw_irq,
.check_sdw_irq = mtl_dsp_check_sdw_irq,
.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
.check_ipc_irq = mtl_dsp_check_ipc_irq,
.cl_init = mtl_dsp_cl_init,
.power_down_dsp = mtl_power_down_dsp,
.disable_interrupts = mtl_dsp_disable_interrupts,
.hw_ip_version = SOF_INTEL_ACE_1_0,
};
EXPORT_SYMBOL_NS(arl_s_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);

View File

@ -80,10 +80,41 @@ static const struct sof_dev_desc arl_desc = {
.ops_free = hda_ops_free,
};
static const struct sof_dev_desc arl_s_desc = {
.use_acpi_target_states = true,
.machines = snd_soc_acpi_intel_arl_machines,
.alt_machines = snd_soc_acpi_intel_arl_sdw_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &arl_s_chip_info,
.ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
.ipc_default = SOF_IPC_TYPE_4,
.dspless_mode_supported = true, /* Only supported for HDaudio */
.default_fw_path = {
[SOF_IPC_TYPE_4] = "intel/sof-ipc4/arl-s",
},
.default_lib_path = {
[SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/arl-s",
},
.default_tplg_path = {
[SOF_IPC_TYPE_4] = "intel/sof-ace-tplg",
},
.default_fw_filename = {
[SOF_IPC_TYPE_4] = "sof-arl-s.ri",
},
.nocodec_tplg_filename = "sof-arl-nocodec.tplg",
.ops = &sof_mtl_ops,
.ops_init = sof_mtl_ops_init,
.ops_free = hda_ops_free,
};
/* PCI IDs */
static const struct pci_device_id sof_pci_ids[] = {
{ PCI_DEVICE_DATA(INTEL, HDA_MTL, &mtl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, &arl_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, &arl_s_desc) },
{ PCI_DEVICE_DATA(INTEL, HDA_ARL, &arl_desc) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sof_pci_ids);

View File

@ -3447,6 +3447,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
case USB_ID(0x1235, 0x8213): /* Focusrite Scarlett 8i6 3rd Gen */
case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */
case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */
case USB_ID(0x1235, 0x8218): /* Focusrite Scarlett Solo 4th Gen */
case USB_ID(0x1235, 0x8219): /* Focusrite Scarlett 2i2 4th Gen */
case USB_ID(0x1235, 0x821a): /* Focusrite Scarlett 4i4 4th Gen */
case USB_ID(0x1235, 0x8206): /* Focusrite Clarett 2Pre USB */
case USB_ID(0x1235, 0x8207): /* Focusrite Clarett 4Pre USB */
case USB_ID(0x1235, 0x8208): /* Focusrite Clarett 8Pre USB */

File diff suppressed because it is too large Load Diff

View File

@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
* *
*****************************************************************************/
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 16)
typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t;
@ -267,7 +267,10 @@ typedef int __bitwise snd_pcm_format_t;
typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX ((__force snd_pcm_subformat_t) 1)
#define SNDRV_PCM_SUBFORMAT_MSBITS_20 ((__force snd_pcm_subformat_t) 2)
#define SNDRV_PCM_SUBFORMAT_MSBITS_24 ((__force snd_pcm_subformat_t) 3)
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_MSBITS_24
#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */