|
@@ -1091,6 +1091,19 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * This precalculated table contains all (vag_val * 100 / lo_calcntrl) results
|
|
|
+ * to select an appropriate lo_vol_* in SGTL5000_CHIP_LINE_OUT_VOL
|
|
|
+ * The calculatation was done for all possible register values which
|
|
|
+ * is the array index and the following formula: 10^((idx−15)/40) * 100
|
|
|
+ */
|
|
|
+static const u8 vol_quot_table[] = {
|
|
|
+ 42, 45, 47, 50, 53, 56, 60, 63,
|
|
|
+ 67, 71, 75, 79, 84, 89, 94, 100,
|
|
|
+ 106, 112, 119, 126, 133, 141, 150, 158,
|
|
|
+ 168, 178, 188, 200, 211, 224, 237, 251
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* sgtl5000 has 3 internal power supplies:
|
|
|
* 1. VAG, normally set to vdda/2
|
|
@@ -1112,6 +1125,9 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
|
|
|
u16 lreg_ctrl;
|
|
|
int vag;
|
|
|
int lo_vag;
|
|
|
+ int vol_quot;
|
|
|
+ int lo_vol;
|
|
|
+ size_t i;
|
|
|
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
|
|
|
|
|
|
vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
|
|
@@ -1216,6 +1232,28 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
|
|
|
SGTL5000_LINE_OUT_CURRENT_360u <<
|
|
|
SGTL5000_LINE_OUT_CURRENT_SHIFT);
|
|
|
|
|
|
+ /*
|
|
|
+ * Set lineout output level in range (0..31)
|
|
|
+ * the same value is used for right and left channel
|
|
|
+ *
|
|
|
+ * Searching for a suitable index solving this formula:
|
|
|
+ * idx = 40 * log10(vag_val / lo_cagcntrl) + 15
|
|
|
+ */
|
|
|
+ vol_quot = (vag * 100) / lo_vag;
|
|
|
+ lo_vol = 0;
|
|
|
+ for (i = 0; i < ARRAY_SIZE(vol_quot_table); i++) {
|
|
|
+ if (vol_quot >= vol_quot_table[i])
|
|
|
+ lo_vol = i;
|
|
|
+ else
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL,
|
|
|
+ SGTL5000_LINE_OUT_VOL_RIGHT_MASK |
|
|
|
+ SGTL5000_LINE_OUT_VOL_LEFT_MASK,
|
|
|
+ lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT |
|
|
|
+ lo_vol << SGTL5000_LINE_OUT_VOL_LEFT_SHIFT);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|