summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/rt286.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
commite5fd91f1ef340da553f7a79da9540c3db711c937 (patch)
treeb11842027dc6641da63f4bcc524f8678263304a3 /sound/soc/codecs/rt286.c
parent2a9b0348e685a63d97486f6749622b61e9e3292f (diff)
Linux-libre 4.2-gnu
Diffstat (limited to 'sound/soc/codecs/rt286.c')
-rw-r--r--sound/soc/codecs/rt286.c130
1 files changed, 23 insertions, 107 deletions
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 0fcda35a3..5c43e263b 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -31,12 +31,15 @@
#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,7 +48,6 @@ 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[] = {
@@ -185,94 +187,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 +215,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 +223,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 +234,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 +275,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 +306,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 +314,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 +322,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 +901,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 +928,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
default:
break;
}
- codec->dapm.bias_level = level;
return 0;
}
@@ -1173,8 +1088,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),
@@ -1247,6 +1162,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
}
rt286->index_cache = rt286_index_def;
+ rt286->index_cache_size = INDEX_CACHE_SIZE;
rt286->i2c = i2c;
i2c_set_clientdata(i2c, rt286);