[alsa-devel] [PATCH 1/2] ASoC: rt286: Fix potencial crash in jd function
We assign rt286->codec in rt286_probe. If rt286_jack_detect is invoked before rt286_probe, rt286->codec will be NULL and cause a kernel panic.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt286.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 2eafbcf..3d69cb4 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -306,6 +306,8 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) *hp = false; *mic = false;
+ if (!rt286->codec) + return -EINVAL; if (rt286->pdata.cbj_en) { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); *hp = buf & 0x80000000;
The patch add the customize setting for Dell Dino project.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt286.c | 25 ++++++++++++++++++++++++- sound/soc/codecs/rt286.h | 7 +++++++ 2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 3d69cb4..8121c97 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1191,6 +1191,17 @@ static struct dmi_system_id force_combo_jack_table[] = { { } };
+static struct dmi_system_id dmi_dell_dino[] = { + { + .ident = "Dell Dino", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_BOARD_NAME, "0144P8") + } + }, + { } +}; + static int rt286_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1226,7 +1237,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (pdata) rt286->pdata = *pdata;
- if (dmi_check_system(force_combo_jack_table)) + if (dmi_check_system(force_combo_jack_table) || + dmi_check_system(dmi_dell_dino)) rt286->pdata.cbj_en = true;
regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); @@ -1265,6 +1277,17 @@ static int rt286_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f);
+ if (dmi_check_system(dmi_dell_dino)) { + regmap_update_bits(rt286->regmap, + RT286_SET_GPIO_MASK, 0x40, 0x40); + regmap_update_bits(rt286->regmap, + RT286_SET_GPIO_DIRECTION, 0x40, 0x40); + regmap_update_bits(rt286->regmap, + RT286_SET_GPIO_DATA, 0x40, 0x40); + regmap_update_bits(rt286->regmap, + RT286_GPIO_CTRL, 0xc, 0x8); + } + if (rt286->i2c->irq) { ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index b539b73..7130edb 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h @@ -117,6 +117,12 @@ VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0) #define RT286_PROC_COEF\ VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0) +#define RT286_SET_GPIO_MASK\ + VERB_CMD(AC_VERB_SET_GPIO_MASK, RT286_AUDIO_FUNCTION_GROUP, 0) +#define RT286_SET_GPIO_DIRECTION\ + VERB_CMD(AC_VERB_SET_GPIO_DIRECTION, RT286_AUDIO_FUNCTION_GROUP, 0) +#define RT286_SET_GPIO_DATA\ + VERB_CMD(AC_VERB_SET_GPIO_DATA, RT286_AUDIO_FUNCTION_GROUP, 0)
/* Index registers */ #define RT286_A_BIAS_CTRL1 0x01 @@ -131,6 +137,7 @@ #define RT286_POWER_CTRL3 0x0f #define RT286_MIC1_DET_CTRL 0x19 #define RT286_MISC_CTRL1 0x20 +#define RT286_GPIO_CTRL 0x29 #define RT286_IRQ_CTRL 0x33 #define RT286_PLL_CTRL1 0x49 #define RT286_CBJ_CTRL1 0x4f
On Thu, Feb 05, 2015 at 04:40:34PM +0800, Bard Liao wrote:
The patch add the customize setting for Dell Dino project.
I've applied this to get the support in for v3.20 but...
- if (dmi_check_system(dmi_dell_dino)) {
regmap_update_bits(rt286->regmap,
RT286_SET_GPIO_MASK, 0x40, 0x40);
regmap_update_bits(rt286->regmap,
RT286_SET_GPIO_DIRECTION, 0x40, 0x40);
regmap_update_bits(rt286->regmap,
RT286_SET_GPIO_DATA, 0x40, 0x40);
regmap_update_bits(rt286->regmap,
RT286_GPIO_CTRL, 0xc, 0x8);
- }
...this code is getting out of hand and really needs to become more data driven instead of having open coded register writes of magic numbers for each case. As the number of machines increases it's going to become difficult to manage and hard to restructure handling of features if the driver changes.
What I'd suggest is to define a struct with all the quirks that might be applied, put all the machines in a table and then figure out which one matches the current one by looking at that table (dmi_first_match() might be helpful here). The code can then look at the struct and make whatever configuration changes are required.
participants (2)
-
Bard Liao
-
Mark Brown