История изменений
Исправление metawishmaster, (текущая версия) :
вообще-то, чтобы хоть как-то работало я изменил две функции:
static int avs_es8336_speaker_power_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_card *card = w->dapm->card;
struct snd_soc_dai *codec_dai;
struct gpio_desc *gpio;
bool speaker_en;
codec_dai = snd_soc_card_get_codec_dai(card, ES8336_CODEC_DAI);
// gpio = gpiod_get_optional(codec_dai->dev, "speakers-enable", GPIOD_OUT_LOW);
speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
if (SND_SOC_DAPM_EVENT_ON(event))
msleep(70);
// printk("gpiod_set_value_cansleep(gpio, %d)\n", speaker_en);
// gpiod_set_value_cansleep(gpio, speaker_en);
return 0;
}
и
static irqreturn_t es8316_irq(int irq, void *data)
{
struct es8316_priv *es8316 = data;
struct snd_soc_component *comp = es8316->component;
static struct gpio_desc *gpio = NULL;
unsigned int flags;
mutex_lock(&es8316->lock);
regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
if (flags == 0x00)
goto out; /* Powered-down / reset */
/* Catch spurious IRQ before set_jack is called */
if (!es8316->jack)
goto out;
if (es8316->jd_inverted)
flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
dev_info(comp->dev, "gpio flags %#04x\n", flags);
if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
/* Jack removed, or spurious IRQ? */
if (es8316->jack->status & SND_JACK_MICROPHONE)
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
if (es8316->jack->status & SND_JACK_HEADPHONE) {
snd_soc_jack_report(es8316->jack, 0,
SND_JACK_HEADSET | SND_JACK_BTN_0);
dev_info(comp->dev, "jack unplugged\n");
if (gpio)
devm_gpiod_put(comp->dev, gpio);
gpio = devm_gpiod_get_optional(comp->dev, "speakers-enable", GPIOD_OUT_LOW);
gpiod_set_value_cansleep(gpio, 0);
if (IS_ERR(gpio))
return dev_err_probe(comp->dev, PTR_ERR(gpio), "Get gpiod failed: %ld\n",
PTR_ERR(gpio));
} printk("spurious IRQ\n");
} else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
/* Jack inserted, determine type */
es8316_enable_micbias_for_mic_gnd_short_detect(comp);
regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
if (es8316->jd_inverted)
flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
dev_info(comp->dev, "gpio flags %#04x\n", flags);
if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
/* Jack unplugged underneath us */
printk("Jack unplugged underneath u\n");
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
} else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
printk("Open, headset\n");
/* Open, headset */
snd_soc_jack_report(es8316->jack,
SND_JACK_HEADSET,
SND_JACK_HEADSET);
/* Keep mic-gnd-short detection on for button press */
} else {
printk("HEADPHONES\n");
if (gpio)
devm_gpiod_put(comp->dev, gpio);
gpio = devm_gpiod_get_optional(comp->dev, "speakers-enable", GPIOD_OUT_HIGH);
/* Shorted, headphones */
gpiod_set_value_cansleep(gpio, 1);
snd_soc_jack_report(es8316->jack,
SND_JACK_HEADPHONE,
SND_JACK_HEADSET);
/* No longer need mic-gnd-short detection */
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
}
} else if (es8316->jack->status & SND_JACK_MICROPHONE) {
/* Interrupt while jack inserted, report button state */
if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
/* Open, button release */
printk("Jack button released\n");
snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
} else {
/* Short, button press */
printk("Jack button pressed\n");
snd_soc_jack_report(es8316->jack,
SND_JACK_BTN_0,
SND_JACK_BTN_0);
}
}
out:
mutex_unlock(&es8316->lock);
return IRQ_HANDLED;
}
но, конечно «struct gpio_desc *gpio» хотелось бы заныкать в какое-нить private поле (что-то похожее было в том патче, который выводил ядро из душевного равновесия)
но в какое - я пока не разобрался :-\
там же у одной карточки есть (или может быть?) несколько поддевайсов, и на какое приходит прерывание тоже пока не понятно :-\
Вы не можете подсказать, в каком направлении копать?
Исходная версия metawishmaster, :
вообще-то, чтобы хоть как-то работало я изменил две функции?
static int avs_es8336_speaker_power_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_card *card = w->dapm->card;
struct snd_soc_dai *codec_dai;
struct gpio_desc *gpio;
bool speaker_en;
codec_dai = snd_soc_card_get_codec_dai(card, ES8336_CODEC_DAI);
// gpio = gpiod_get_optional(codec_dai->dev, "speakers-enable", GPIOD_OUT_LOW);
speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
if (SND_SOC_DAPM_EVENT_ON(event))
msleep(70);
// printk("gpiod_set_value_cansleep(gpio, %d)\n", speaker_en);
// gpiod_set_value_cansleep(gpio, speaker_en);
return 0;
}
и
static irqreturn_t es8316_irq(int irq, void *data)
{
struct es8316_priv *es8316 = data;
struct snd_soc_component *comp = es8316->component;
static struct gpio_desc *gpio = NULL;
unsigned int flags;
mutex_lock(&es8316->lock);
regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
if (flags == 0x00)
goto out; /* Powered-down / reset */
/* Catch spurious IRQ before set_jack is called */
if (!es8316->jack)
goto out;
if (es8316->jd_inverted)
flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
dev_info(comp->dev, "gpio flags %#04x\n", flags);
if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
/* Jack removed, or spurious IRQ? */
if (es8316->jack->status & SND_JACK_MICROPHONE)
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
if (es8316->jack->status & SND_JACK_HEADPHONE) {
snd_soc_jack_report(es8316->jack, 0,
SND_JACK_HEADSET | SND_JACK_BTN_0);
dev_info(comp->dev, "jack unplugged\n");
if (gpio)
devm_gpiod_put(comp->dev, gpio);
gpio = devm_gpiod_get_optional(comp->dev, "speakers-enable", GPIOD_OUT_LOW);
gpiod_set_value_cansleep(gpio, 0);
if (IS_ERR(gpio))
return dev_err_probe(comp->dev, PTR_ERR(gpio), "Get gpiod failed: %ld\n",
PTR_ERR(gpio));
} printk("spurious IRQ\n");
} else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
/* Jack inserted, determine type */
es8316_enable_micbias_for_mic_gnd_short_detect(comp);
regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
if (es8316->jd_inverted)
flags ^= ES8316_GPIO_FLAG_HP_NOT_INSERTED;
dev_info(comp->dev, "gpio flags %#04x\n", flags);
if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
/* Jack unplugged underneath us */
printk("Jack unplugged underneath u\n");
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
} else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
printk("Open, headset\n");
/* Open, headset */
snd_soc_jack_report(es8316->jack,
SND_JACK_HEADSET,
SND_JACK_HEADSET);
/* Keep mic-gnd-short detection on for button press */
} else {
printk("HEADPHONES\n");
if (gpio)
devm_gpiod_put(comp->dev, gpio);
gpio = devm_gpiod_get_optional(comp->dev, "speakers-enable", GPIOD_OUT_HIGH);
/* Shorted, headphones */
gpiod_set_value_cansleep(gpio, 1);
snd_soc_jack_report(es8316->jack,
SND_JACK_HEADPHONE,
SND_JACK_HEADSET);
/* No longer need mic-gnd-short detection */
es8316_disable_micbias_for_mic_gnd_short_detect(comp);
}
} else if (es8316->jack->status & SND_JACK_MICROPHONE) {
/* Interrupt while jack inserted, report button state */
if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
/* Open, button release */
printk("Jack button released\n");
snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
} else {
/* Short, button press */
printk("Jack button pressed\n");
snd_soc_jack_report(es8316->jack,
SND_JACK_BTN_0,
SND_JACK_BTN_0);
}
}
out:
mutex_unlock(&es8316->lock);
return IRQ_HANDLED;
}
но, конечно «struct gpio_desc *gpio» хотелось бы заныкать в какое-нить private поле (что-то похожее было в том патче, который выводил ядро из душевного равновесия)
но в какое - я пока не разобрался :-\
там же у одной карточки есть (или может быть?) несколько поддевайсов, и на какое приходит прерывание тоже пока не понятно :-\
Вы не можете подсказать, в каком направлении копать?