Commit cf1f9e5d authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000' and...

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000' and 'asoc/topic/sh' into asoc-next
...@@ -5,11 +5,6 @@ Required properties: ...@@ -5,11 +5,6 @@ Required properties:
- compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board, - compatible - "samsung,odroidxu3-audio" - for Odroid XU3 board,
"samsung,odroidxu4-audio" - for Odroid XU4 board "samsung,odroidxu4-audio" - for Odroid XU4 board
- model - the user-visible name of this sound complex - 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 - clocks - should contain entries matching clock names in the clock-names
property property
- clock-names - should contain following entries: - clock-names - should contain following entries:
...@@ -32,12 +27,18 @@ Required properties: ...@@ -32,12 +27,18 @@ Required properties:
For Odroid XU4: For Odroid XU4:
no entries 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: Example:
sound { sound {
compatible = "samsung,odroidxu3-audio"; compatible = "samsung,odroidxu3-audio";
samsung,cpu-dai = <&i2s0>;
samsung,codec-dai = <&max98090>;
model = "Odroid-XU3"; model = "Odroid-XU3";
samsung,audio-routing = samsung,audio-routing =
"Headphone Jack", "HPL", "Headphone Jack", "HPL",
......
...@@ -74,6 +74,20 @@ static const struct reg_default sgtl5000_reg_defaults[] = { ...@@ -74,6 +74,20 @@ static const struct reg_default sgtl5000_reg_defaults[] = {
{ SGTL5000_DAP_AVC_DECAY, 0x0050 }, { 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 */ /* regulator supplies for sgtl5000, VDDD is an optional external supply */
enum sgtl5000_regulator_supplies { enum sgtl5000_regulator_supplies {
VDDA, VDDA,
...@@ -382,6 +396,65 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol, ...@@ -382,6 +396,65 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
return 0; 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); static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
/* tlv for mic gain, 0db 20db 30db 40db */ /* tlv for mic gain, 0db 20db 30db 40db */
...@@ -396,6 +469,12 @@ static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0); ...@@ -396,6 +469,12 @@ static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
/* tlv for lineout volume, 31 steps of .5db each */ /* tlv for lineout volume, 31 steps of .5db each */
static const DECLARE_TLV_DB_SCALE(lineout_volume, -1550, 50, 0); 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[] = { static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
/* SOC_DOUBLE_S8_TLV with invert */ /* SOC_DOUBLE_S8_TLV with invert */
{ {
...@@ -434,6 +513,16 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { ...@@ -434,6 +513,16 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
0x1f, 1, 0x1f, 1,
lineout_volume), lineout_volume),
SOC_SINGLE("Lineout Playback Switch", SGTL5000_CHIP_ANA_CTRL, 8, 1, 1), 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 */ /* mute the codec used by alsa core */
......
...@@ -44,7 +44,7 @@ struct s3c24xx_uda134x { ...@@ -44,7 +44,7 @@ struct s3c24xx_uda134x {
static unsigned int rates[33 * 2]; static unsigned int rates[33 * 2];
#ifdef ENFORCE_RATES #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), .count = ARRAY_SIZE(rates),
.list = rates, .list = rates,
.mask = 0, .mask = 0,
......
...@@ -301,7 +301,12 @@ struct fsi_master { ...@@ -301,7 +301,12 @@ struct fsi_master {
spinlock_t lock; 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 * basic read write function
...@@ -489,12 +494,6 @@ static void fsi_count_fifo_err(struct fsi_priv *fsi) ...@@ -489,12 +494,6 @@ static void fsi_count_fifo_err(struct fsi_priv *fsi)
/* /*
* fsi_stream_xx() function * 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, static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment