mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
ASoC: rockchip: multicodecs: fix the invalid jack reference without codec_hp_det and gpio detection
The crash log: ======== [ 6.807722] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 [ 6.812273] Mem abort info: [ 6.812596] ESR = 0x96000006 [ 6.812899] EC = 0x25: DABT (current EL), IL = 32 bits [ 6.813439] SET = 0, FnV = 0 [ 6.813737] EA = 0, S1PTW = 0 [ 6.814037] Data abort info: [ 6.814316] ISV = 0, ISS = 0x00000006 [ 6.814733] CM = 0, WnR = 0 [ 6.815042] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000002585000 [ 6.815676] [0000000000000000] pgd=0000000002584003, p4d=0000000002584003, pud=0000000002584003, pmd=0000000000000000 [ 6.816819] Internal error: Oops: 96000006 [#1] PREEMPT SMP [ 6.817341] Modules linked in: [ 6.817664] CPU: 1 PID: 64 Comm: kworker/u8:1 Not tainted 5.10.110 #151 [ 6.818268] Hardware name: Rockchip RK3308B-S evb analog mic v11 board (DT) [ 6.818923] Workqueue: events_power_efficient rk3308_codec_hpdetect_work [ 6.819549] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) [ 6.820112] pc : __pi_strcmp+0x90/0x158 [ 6.820480] lr : dapm_find_widget+0xb0/0xec [ 6.820871] sp : ffffffc010cfbc20 Signed-off-by: Xing Zheng <zhengxing@rock-chips.com> Change-Id: I6b0e8823353c34eb669e57a633e83a9945275a14
This commit is contained in:
@@ -75,32 +75,6 @@ struct multicodecs_data {
|
||||
struct input_dev_poller *poller;
|
||||
};
|
||||
|
||||
static struct snd_soc_jack_pin jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
}, {
|
||||
.pin = "Headset Mic",
|
||||
.mask = SND_JACK_MICROPHONE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_jack_zone headset_zones[] = {
|
||||
{
|
||||
.min_mv = 0,
|
||||
.max_mv = 222,
|
||||
.jack_type = SND_JACK_HEADPHONE,
|
||||
}, {
|
||||
.min_mv = 223,
|
||||
.max_mv = 1500,
|
||||
.jack_type = SND_JACK_HEADSET,
|
||||
}, {
|
||||
.min_mv = 1501,
|
||||
.max_mv = UINT_MAX,
|
||||
.jack_type = SND_JACK_HEADPHONE,
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned int headset_extcon_cable[] = {
|
||||
EXTCON_JACK_MICROPHONE,
|
||||
EXTCON_JACK_HEADPHONE,
|
||||
@@ -397,19 +371,59 @@ static int rk_dailink_init(struct snd_soc_pcm_runtime *rtd)
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_jack *jack_headset;
|
||||
int ret, irq;
|
||||
struct snd_soc_jack_pin *pins;
|
||||
struct snd_soc_jack_zone *zones;
|
||||
struct snd_soc_jack_pin jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone",
|
||||
.mask = SND_JACK_HEADPHONE,
|
||||
}, {
|
||||
.pin = "Headset Mic",
|
||||
.mask = SND_JACK_MICROPHONE,
|
||||
},
|
||||
};
|
||||
struct snd_soc_jack_zone headset_zones[] = {
|
||||
{
|
||||
.min_mv = 0,
|
||||
.max_mv = 222,
|
||||
.jack_type = SND_JACK_HEADPHONE,
|
||||
}, {
|
||||
.min_mv = 223,
|
||||
.max_mv = 1500,
|
||||
.jack_type = SND_JACK_HEADSET,
|
||||
}, {
|
||||
.min_mv = 1501,
|
||||
.max_mv = UINT_MAX,
|
||||
.jack_type = SND_JACK_HEADPHONE,
|
||||
}
|
||||
};
|
||||
|
||||
if ((!mc_data->codec_hp_det) && (gpiod_to_irq(mc_data->hp_det_gpio) < 0)) {
|
||||
dev_info(card->dev, "Don't need to map headset detect gpio to irq\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_headset = devm_kzalloc(card->dev, sizeof(*jack_headset), GFP_KERNEL);
|
||||
if (!jack_headset)
|
||||
return -ENOMEM;
|
||||
|
||||
pins = devm_kmemdup(card->dev, jack_pins,
|
||||
sizeof(*jack_pins) * ARRAY_SIZE(jack_pins), GFP_KERNEL);
|
||||
if (!pins)
|
||||
return -ENOMEM;
|
||||
|
||||
zones = devm_kmemdup(card->dev, headset_zones,
|
||||
sizeof(*headset_zones) * ARRAY_SIZE(headset_zones), GFP_KERNEL);
|
||||
if (!zones)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_soc_card_jack_new(card, "Headset",
|
||||
SND_JACK_HEADSET,
|
||||
jack_headset,
|
||||
jack_pins, ARRAY_SIZE(jack_pins));
|
||||
pins, ARRAY_SIZE(jack_pins));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = snd_soc_jack_add_zones(jack_headset, ARRAY_SIZE(headset_zones),
|
||||
headset_zones);
|
||||
ret = snd_soc_jack_add_zones(jack_headset, ARRAY_SIZE(headset_zones), zones);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -436,8 +450,6 @@ static int rk_dailink_init(struct snd_soc_pcm_runtime *rtd)
|
||||
|
||||
queue_delayed_work(system_power_efficient_wq,
|
||||
&mc_data->handler, msecs_to_jiffies(50));
|
||||
} else {
|
||||
dev_warn(card->dev, "Failed to map headset detect gpio to irq");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user