These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / sound / soc / codecs / rt286.c
index 0fcda35..af2ed77 100644 (file)
 #include <sound/jack.h>
 #include <linux/workqueue.h>
 #include <sound/rt286.h>
-#include <sound/hda_verbs.h>
 
+#include "rl6347a.h"
 #include "rt286.h"
 
 #define RT286_VENDOR_ID 0x10ec0286
 #define RT288_VENDOR_ID 0x10ec0288
 
 struct rt286_priv {
+       struct reg_default *index_cache;
+       int index_cache_size;
        struct regmap *regmap;
        struct snd_soc_codec *codec;
        struct rt286_platform_data pdata;
@@ -45,10 +47,9 @@ struct rt286_priv {
        struct delayed_work jack_detect_work;
        int sys_clk;
        int clk_id;
-       struct reg_default *index_cache;
 };
 
-static struct reg_default rt286_index_def[] = {
+static const struct reg_default rt286_index_def[] = {
        { 0x01, 0xaaaa },
        { 0x02, 0x8aaa },
        { 0x03, 0x0002 },
@@ -185,94 +186,6 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
        }
 }
 
-static int rt286_hw_write(void *context, unsigned int reg, unsigned int value)
-{
-       struct i2c_client *client = context;
-       struct rt286_priv *rt286 = i2c_get_clientdata(client);
-       u8 data[4];
-       int ret, i;
-
-       /* handle index registers */
-       if (reg <= 0xff) {
-               rt286_hw_write(client, RT286_COEF_INDEX, reg);
-               for (i = 0; i < INDEX_CACHE_SIZE; i++) {
-                       if (reg == rt286->index_cache[i].reg) {
-                               rt286->index_cache[i].def = value;
-                               break;
-                       }
-
-               }
-               reg = RT286_PROC_COEF;
-       }
-
-       data[0] = (reg >> 24) & 0xff;
-       data[1] = (reg >> 16) & 0xff;
-       /*
-        * 4 bit VID: reg should be 0
-        * 12 bit VID: value should be 0
-        * So we use an OR operator to handle it rather than use if condition.
-        */
-       data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
-       data[3] = value & 0xff;
-
-       ret = i2c_master_send(client, data, 4);
-
-       if (ret == 4)
-               return 0;
-       else
-               pr_err("ret=%d\n", ret);
-       if (ret < 0)
-               return ret;
-       else
-               return -EIO;
-}
-
-static int rt286_hw_read(void *context, unsigned int reg, unsigned int *value)
-{
-       struct i2c_client *client = context;
-       struct i2c_msg xfer[2];
-       int ret;
-       __be32 be_reg;
-       unsigned int index, vid, buf = 0x0;
-
-       /* handle index registers */
-       if (reg <= 0xff) {
-               rt286_hw_write(client, RT286_COEF_INDEX, reg);
-               reg = RT286_PROC_COEF;
-       }
-
-       reg = reg | 0x80000;
-       vid = (reg >> 8) & 0xfff;
-
-       if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
-               index = (reg >> 8) & 0xf;
-               reg = (reg & ~0xf0f) | index;
-       }
-       be_reg = cpu_to_be32(reg);
-
-       /* Write register */
-       xfer[0].addr = client->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 4;
-       xfer[0].buf = (u8 *)&be_reg;
-
-       /* Read data */
-       xfer[1].addr = client->addr;
-       xfer[1].flags = I2C_M_RD;
-       xfer[1].len = 4;
-       xfer[1].buf = (u8 *)&buf;
-
-       ret = i2c_transfer(client->adapter, xfer, 2);
-       if (ret < 0)
-               return ret;
-       else if (ret != 2)
-               return -EIO;
-
-       *value = be32_to_cpu(buf);
-
-       return 0;
-}
-
 #ifdef CONFIG_PM
 static void rt286_index_sync(struct snd_soc_codec *codec)
 {
@@ -301,6 +214,7 @@ static int rt286_support_power_controls[] = {
 
 static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 {
+       struct snd_soc_dapm_context *dapm;
        unsigned int val, buf;
 
        *hp = false;
@@ -308,6 +222,9 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 
        if (!rt286->codec)
                return -EINVAL;
+
+       dapm = snd_soc_codec_get_dapm(rt286->codec);
+
        if (rt286->pdata.cbj_en) {
                regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
                *hp = buf & 0x80000000;
@@ -316,14 +233,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
                        regmap_update_bits(rt286->regmap,
                                RT286_DC_GAIN, 0x200, 0x200);
 
-                       snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
-                                                       "HV");
-                       snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
-                                                       "VREF");
+                       snd_soc_dapm_force_enable_pin(dapm, "HV");
+                       snd_soc_dapm_force_enable_pin(dapm, "VREF");
                        /* power LDO1 */
-                       snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
-                                                       "LDO1");
-                       snd_soc_dapm_sync(&rt286->codec->dapm);
+                       snd_soc_dapm_force_enable_pin(dapm, "LDO1");
+                       snd_soc_dapm_sync(dapm);
 
                        regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
                        msleep(50);
@@ -360,11 +274,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
                *mic = buf & 0x80000000;
        }
 
-       snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV");
-       snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF");
+       snd_soc_dapm_disable_pin(dapm, "HV");
+       snd_soc_dapm_disable_pin(dapm, "VREF");
        if (!*hp)
-               snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1");
-       snd_soc_dapm_sync(&rt286->codec->dapm);
+               snd_soc_dapm_disable_pin(dapm, "LDO1");
+       snd_soc_dapm_sync(dapm);
 
        return 0;
 }
@@ -391,6 +305,7 @@ static void rt286_jack_detect_work(struct work_struct *work)
 
 int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 {
+       struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
        struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
 
        rt286->jack = jack;
@@ -398,7 +313,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
        if (jack) {
                /* enable IRQ */
                if (rt286->jack->status & SND_JACK_HEADPHONE)
-                       snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1");
+                       snd_soc_dapm_force_enable_pin(dapm, "LDO1");
                regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
                /* Send an initial empty report */
                snd_soc_jack_report(rt286->jack, rt286->jack->status,
@@ -406,9 +321,9 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
        } else {
                /* disable IRQ */
                regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0);
-               snd_soc_dapm_disable_pin(&codec->dapm, "LDO1");
+               snd_soc_dapm_disable_pin(dapm, "LDO1");
        }
-       snd_soc_dapm_sync(&codec->dapm);
+       snd_soc_dapm_sync(dapm);
 
        return 0;
 }
@@ -985,7 +900,7 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
 {
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
-               if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
+               if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
                        snd_soc_write(codec,
                                RT286_SET_AUDIO_POWER, AC_PWRST_D0);
                        snd_soc_update_bits(codec,
@@ -1012,7 +927,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
        default:
                break;
        }
-       codec->dapm.bias_level = level;
 
        return 0;
 }
@@ -1173,8 +1087,8 @@ static const struct regmap_config rt286_regmap = {
        .max_register = 0x02370100,
        .volatile_reg = rt286_volatile_register,
        .readable_reg = rt286_readable_register,
-       .reg_write = rt286_hw_write,
-       .reg_read = rt286_hw_read,
+       .reg_write = rl6347a_hw_write,
+       .reg_read = rl6347a_hw_read,
        .cache_type = REGCACHE_RBTREE,
        .reg_defaults = rt286_reg,
        .num_reg_defaults = ARRAY_SIZE(rt286_reg),
@@ -1193,7 +1107,7 @@ static const struct acpi_device_id rt286_acpi_match[] = {
 };
 MODULE_DEVICE_TABLE(acpi, rt286_acpi_match);
 
-static struct dmi_system_id force_combo_jack_table[] = {
+static const struct dmi_system_id force_combo_jack_table[] = {
        {
                .ident = "Intel Wilson Beach",
                .matches = {
@@ -1203,7 +1117,7 @@ static struct dmi_system_id force_combo_jack_table[] = {
        { }
 };
 
-static struct dmi_system_id dmi_dell_dino[] = {
+static const struct dmi_system_id dmi_dell_dino[] = {
        {
                .ident = "Dell Dino",
                .matches = {
@@ -1242,11 +1156,16 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
        }
        if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
                dev_err(&i2c->dev,
-                       "Device with ID register %x is not rt286\n", val);
+                       "Device with ID register %#x is not rt286\n", val);
                return -ENODEV;
        }
 
-       rt286->index_cache = rt286_index_def;
+       rt286->index_cache = devm_kmemdup(&i2c->dev, rt286_index_def,
+                                         sizeof(rt286_index_def), GFP_KERNEL);
+       if (!rt286->index_cache)
+               return -ENOMEM;
+
+       rt286->index_cache_size = INDEX_CACHE_SIZE;
        rt286->i2c = i2c;
        i2c_set_clientdata(i2c, rt286);
 
@@ -1343,7 +1262,6 @@ static int rt286_i2c_remove(struct i2c_client *i2c)
 static struct i2c_driver rt286_i2c_driver = {
        .driver = {
                   .name = "rt286",
-                  .owner = THIS_MODULE,
                   .acpi_match_table = ACPI_PTR(rt286_acpi_match),
                   },
        .probe = rt286_i2c_probe,