@@ -26,6 +26,11 @@ Optional properties:
3 - MICBIAS output is connected to AVDD,
If this node is not mentioned or if the value is incorrect, then MicBias
is powered down.
+- ai3x-ocmv - Output Common-Mode Voltage selection:
+ 0 - 1.35V,
+ 1 - 1.5V,
+ 2 - 1.65V,
+ 3 - 1.8V
- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the
device as covered in Documentation/devicetree/bindings/regulator/regulator.txt
@@ -93,6 +93,8 @@ struct aic3x_priv {
/* Selects the micbias voltage */
enum aic3x_micbias_voltage micbias_vg;
+ /* Output Common-Mode Voltage */
+ u8 ocmv;
};
static const struct reg_default aic3x_reg[] = {
@@ -1572,6 +1574,10 @@ static int aic3x_init(struct snd_soc_codec *codec)
break;
}
+ /* Output common-mode voltage = 1.5 V */
+ snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK,
+ aic3x->ocmv << HPOUT_SC_OCMV_SHIFT);
+
return 0;
}
@@ -1699,6 +1705,43 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
},
};
+static void aic3x_configure_ocmv(struct i2c_client *client)
+{
+ struct device_node *np = client->dev.of_node;
+ struct aic3x_priv *aic3x = i2c_get_clientdata(client);
+ u32 value;
+ int dvdd, avdd;
+
+ if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) {
+ /* OCMV setting is forced by DT */
+ if (value <= 3) {
+ aic3x->ocmv = value;
+ return;
+ }
+ }
+
+ dvdd = regulator_get_voltage(aic3x->supplies[1].consumer);
+ avdd = regulator_get_voltage(aic3x->supplies[2].consumer);
+
+ if (avdd > 3600000 || dvdd > 1950000) {
+ dev_warn(&client->dev,
+ "Too high supply voltage(s) AVDD: %d, DVDD: %d\n",
+ avdd, dvdd);
+ } else if (avdd == 3600000 && dvdd == 1950000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_8V;
+ } else if (avdd > 3300000 && dvdd > 1800000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_65V;
+ } else if (avdd > 3000000 && dvdd > 1650000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_5V;
+ } else if (avdd >= 2700000 && dvdd >= 1525000) {
+ aic3x->ocmv = HPOUT_SC_OCMV_1_35V;
+ } else {
+ dev_warn(&client->dev,
+ "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n",
+ avdd, dvdd);
+ }
+}
+
/*
* AIC3X 2 wire address can be up to 4 devices with device addresses
* 0x18, 0x19, 0x1A, 0x1B
@@ -1816,6 +1859,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
goto err_gpio;
}
+ aic3x_configure_ocmv(i2c);
+
if (aic3x->model == AIC3X_MODEL_3007) {
ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
ARRAY_SIZE(aic3007_class_d));
@@ -243,6 +243,14 @@
#define MICBIAS_LEVEL_SHIFT (6)
#define MICBIAS_LEVEL_MASK (3 << 6)
+/* HPOUT_SC */
+#define HPOUT_SC_OCMV_MASK (3 << 6)
+#define HPOUT_SC_OCMV_SHIFT (6)
+#define HPOUT_SC_OCMV_1_35V 0
+#define HPOUT_SC_OCMV_1_5V 1
+#define HPOUT_SC_OCMV_1_65V 2
+#define HPOUT_SC_OCMV_1_8V 3
+
/* headset detection / button API */
/* The AIC3x supports detection of stereo headsets (GND + left + right signal)