diff options
Diffstat (limited to 'sound/soc/codecs/rt286.c')
-rw-r--r-- | sound/soc/codecs/rt286.c | 130 |
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); |