1
0
Fork 0

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000' and 'asoc/topic/sh' into asoc-next

hifive-unleashed-5.1
Mark Brown 2017-07-03 16:15:19 +01:00
commit cf1f9e5d16
4 changed files with 104 additions and 15 deletions

View File

@ -5,11 +5,6 @@ Required properties:
- compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
"samsung,odroidxu4-audio" - for Odroid XU4 board
- model - the user-visible name of this sound complex
- 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
controller
- 'codec' subnode with a 'sound-dai' property containing list of phandles
to the CODEC nodes, first entry must be corresponding to the MAX98090
CODEC and the second entry must be the phandle of the HDMI IP block node
- clocks - should contain entries matching clock names in the clock-names
property
- clock-names - should contain following entries:
@ -32,12 +27,18 @@ Required properties:
For Odroid XU4:
no entries
Required sub-nodes:
- 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
controller
- 'codec' subnode with a 'sound-dai' property containing list of phandles
to the CODEC nodes, first entry must be corresponding to the MAX98090
CODEC and the second entry must be the phandle of the HDMI IP block node
Example:
sound {
compatible = "samsung,odroidxu3-audio";
samsung,cpu-dai = <&i2s0>;
samsung,codec-dai = <&max98090>;
model = "Odroid-XU3";
samsung,audio-routing =
"Headphone Jack", "HPL",

View File

@ -74,6 +74,20 @@ static const struct reg_default sgtl5000_reg_defaults[] = {
{ SGTL5000_DAP_AVC_DECAY, 0x0050 },
};
/* AVC: Threshold dB -> register: pre-calculated values */
static const u16 avc_thr_db2reg[97] = {
0x5168, 0x488E, 0x40AA, 0x39A1, 0x335D, 0x2DC7, 0x28CC, 0x245D, 0x2068,
0x1CE2, 0x19BE, 0x16F1, 0x1472, 0x1239, 0x103E, 0x0E7A, 0x0CE6, 0x0B7F,
0x0A3F, 0x0922, 0x0824, 0x0741, 0x0677, 0x05C3, 0x0522, 0x0493, 0x0414,
0x03A2, 0x033D, 0x02E3, 0x0293, 0x024B, 0x020B, 0x01D2, 0x019F, 0x0172,
0x014A, 0x0126, 0x0106, 0x00E9, 0x00D0, 0x00B9, 0x00A5, 0x0093, 0x0083,
0x0075, 0x0068, 0x005D, 0x0052, 0x0049, 0x0041, 0x003A, 0x0034, 0x002E,
0x0029, 0x0025, 0x0021, 0x001D, 0x001A, 0x0017, 0x0014, 0x0012, 0x0010,
0x000E, 0x000D, 0x000B, 0x000A, 0x0009, 0x0008, 0x0007, 0x0006, 0x0005,
0x0005, 0x0004, 0x0004, 0x0003, 0x0003, 0x0002, 0x0002, 0x0002, 0x0002,
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
/* regulator supplies for sgtl5000, VDDD is an optional external supply */
enum sgtl5000_regulator_supplies {
VDDA,
@ -382,6 +396,65 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
return 0;
}
/*
* custom function to get AVC threshold
*
* The threshold dB is calculated by rearranging the calculation from the
* avc_put_threshold function: register_value = 10^(dB/20) * 0.636 * 2^15 ==>
* dB = ( fls(register_value) - 14.347 ) * 6.02
*
* As this calculation is expensive and the threshold dB values may not exeed
* 0 to 96 we use pre-calculated values.
*/
static int avc_get_threshold(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int db, i;
u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD);
/* register value 0 => -96dB */
if (!reg) {
ucontrol->value.integer.value[0] = 96;
ucontrol->value.integer.value[1] = 96;
return 0;
}
/* get dB from register value (rounded down) */
for (i = 0; avc_thr_db2reg[i] > reg; i++)
;
db = i;
ucontrol->value.integer.value[0] = db;
ucontrol->value.integer.value[1] = db;
return 0;
}
/*
* custom function to put AVC threshold
*
* The register value is calculated by following formula:
* register_value = 10^(dB/20) * 0.636 * 2^15
* As this calculation is expensive and the threshold dB values may not exeed
* 0 to 96 we use pre-calculated values.
*/
static int avc_put_threshold(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int db;
u16 reg;
db = (int)ucontrol->value.integer.value[0];
if (db < 0 || db > 96)
return -EINVAL;
reg = avc_thr_db2reg[db];
snd_soc_write(codec, SGTL5000_DAP_AVC_THRESHOLD, reg);
return 0;
}
static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
/* tlv for mic gain, 0db 20db 30db 40db */
@ -396,6 +469,12 @@ static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
/* tlv for lineout volume, 31 steps of .5db each */
static const DECLARE_TLV_DB_SCALE(lineout_volume, -1550, 50, 0);
/* tlv for dap avc max gain, 0db, 6db, 12db */
static const DECLARE_TLV_DB_SCALE(avc_max_gain, 0, 600, 0);
/* tlv for dap avc threshold, */
static const DECLARE_TLV_DB_MINMAX(avc_threshold, 0, 9600);
static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
/* SOC_DOUBLE_S8_TLV with invert */
{
@ -434,6 +513,16 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
0x1f, 1,
lineout_volume),
SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1),
/* Automatic Volume Control (DAP AVC) */
SOC_SINGLE("AVC Switch", SGTL5000_DAP_AVC_CTRL, 0, 1, 0),
SOC_SINGLE("AVC Hard Limiter Switch", SGTL5000_DAP_AVC_CTRL, 5, 1, 0),
SOC_SINGLE_TLV("AVC Max Gain Volume", SGTL5000_DAP_AVC_CTRL, 12, 2, 0,
avc_max_gain),
SOC_SINGLE("AVC Integrator Response", SGTL5000_DAP_AVC_CTRL, 8, 3, 0),
SOC_SINGLE_EXT_TLV("AVC Threshold Volume", SGTL5000_DAP_AVC_THRESHOLD,
0, 96, 0, avc_get_threshold, avc_put_threshold,
avc_threshold),
};
/* mute the codec used by alsa core */

View File

@ -44,7 +44,7 @@ struct s3c24xx_uda134x {
static unsigned int rates[33 * 2];
#ifdef ENFORCE_RATES
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,

View File

@ -301,7 +301,12 @@ struct fsi_master {
spinlock_t lock;
};
static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
static inline int fsi_stream_is_play(struct fsi_priv *fsi,
struct fsi_stream *io)
{
return &fsi->playback == io;
}
/*
* basic read write function
@ -489,12 +494,6 @@ static void fsi_count_fifo_err(struct fsi_priv *fsi)
/*
* fsi_stream_xx() function
*/
static inline int fsi_stream_is_play(struct fsi_priv *fsi,
struct fsi_stream *io)
{
return &fsi->playback == io;
}
static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
struct snd_pcm_substream *substream)
{