From: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>
Cc: <alsa-devel@alsa-project.org>, <patches@opensource.cirrus.com>,
<linux-kernel@vger.kernel.org>,
Lucas Tanure <tanureal@opensource.cirrus.com>
Subject: [PATCH v2 15/27] ALSA: hda/cs8409: Avoid re-setting the same page as the last access
Date: Wed, 28 Jul 2021 14:43:56 +0100 [thread overview]
Message-ID: <20210728134408.369396-16-vitalyr@opensource.cirrus.com> (raw)
In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com>
From: Lucas Tanure <tanureal@opensource.cirrus.com>
Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Changes in v2:
- No changes
---
sound/pci/hda/patch_cs8409.c | 124 +++++++++++++++++++----------------
sound/pci/hda/patch_cs8409.h | 2 +
2 files changed, 71 insertions(+), 55 deletions(-)
diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c
index bd43c42d5c74..31c9f1a3aeaa 100644
--- a/sound/pci/hda/patch_cs8409.c
+++ b/sound/pci/hda/patch_cs8409.c
@@ -147,18 +147,37 @@ static void cs8409_set_i2c_dev_addr(struct hda_codec *codec, unsigned int addr)
}
}
+/**
+ * cs8409_i2c_set_page - CS8409 I2C set page register.
+ * @codec: the codec instance
+ * @i2c_reg: Page register
+ *
+ * Returns negative on error.
+ */
+static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg)
+{
+ struct cs8409_spec *spec = codec->spec;
+
+ if (spec->paged && (spec->last_page != (i2c_reg >> 8))) {
+ cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8);
+ if (cs8409_i2c_wait_complete(codec) < 0)
+ return -EIO;
+ spec->last_page = i2c_reg >> 8;
+ }
+
+ return 0;
+}
+
/**
* cs8409_i2c_read - CS8409 I2C Read.
* @codec: the codec instance
* @i2c_address: I2C Address
* @i2c_reg: Register to read
- * @paged: Is a paged transaction
*
* CS8409 I2C Read.
* Returns negative on error, otherwise returns read value in bits 0-7.
*/
-static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg,
- unsigned int paged)
+static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg)
{
struct cs8409_spec *spec = codec->spec;
unsigned int i2c_reg_data;
@@ -170,13 +189,10 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un
cs8409_enable_i2c_clock(codec);
cs8409_set_i2c_dev_addr(codec, i2c_address);
- if (paged) {
- cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8);
- if (cs8409_i2c_wait_complete(codec) < 0) {
- codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n",
- __func__, i2c_address, i2c_reg);
- return -EIO;
- }
+ if (cs8409_i2c_set_page(codec, i2c_reg)) {
+ codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n",
+ __func__, i2c_address, i2c_reg);
+ return -EIO;
}
i2c_reg_data = (i2c_reg << 8) & 0x0ffff;
@@ -199,13 +215,12 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un
* @i2c_address: I2C Address
* @i2c_reg: Register to write to
* @i2c_data: Data to write
- * @paged: Is a paged transaction
*
* CS8409 I2C Write.
* Returns negative on error, otherwise returns 0.
*/
static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg,
- unsigned int i2c_data, unsigned int paged)
+ unsigned int i2c_data)
{
struct cs8409_spec *spec = codec->spec;
unsigned int i2c_reg_data;
@@ -216,13 +231,10 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u
cs8409_enable_i2c_clock(codec);
cs8409_set_i2c_dev_addr(codec, i2c_address);
- if (paged) {
- cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8);
- if (cs8409_i2c_wait_complete(codec) < 0) {
- codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n",
- __func__, i2c_address, i2c_reg);
- return -EIO;
- }
+ if (cs8409_i2c_set_page(codec, i2c_reg)) {
+ codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n",
+ __func__, i2c_address, i2c_reg);
+ return -EIO;
}
i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff);
@@ -302,14 +314,14 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va
if (chs & BIT(0)) {
spec->vol[ofs] = *valp;
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
- -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+ -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK);
}
if (chs & BIT(1)) {
ofs++;
valp++;
spec->vol[ofs] = *valp;
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
- -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+ -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK);
}
mutex_unlock(&spec->cs8409_i2c_mux);
break;
@@ -318,7 +330,7 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va
if (chs & BIT(0)) {
spec->vol[ofs] = *valp;
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
- spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
+ spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK);
}
mutex_unlock(&spec->cs8409_i2c_mux);
break;
@@ -344,14 +356,15 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec)
usleep_range(10000, 15000);
spec->cs42l42_suspended = 0;
+ spec->last_page = 0;
mutex_lock(&spec->cs8409_i2c_mux);
/* Clear interrupts, by reading interrupt status registers */
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1);
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1);
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1);
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F);
mutex_unlock(&spec->cs8409_i2c_mux);
@@ -368,20 +381,20 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec)
* Additionally set HSBIAS_SENSE_EN for some variants.
*/
if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE)
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020);
else
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0);
/* Clear WAKE# */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1);
/* Wait ~2.5ms */
usleep_range(2500, 3000);
/* Set mode WAKE# output follows the combination logic directly */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0);
/* Clear interrupts status */
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
/* Enable interrupt */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
mutex_unlock(&spec->cs8409_i2c_mux);
}
@@ -394,20 +407,20 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec)
mutex_lock(&spec->cs8409_i2c_mux);
/* Clear interrupts */
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1);
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF, 1);
- cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1);
-
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF);
+ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
+
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80);
/* Wait ~110ms*/
usleep_range(110000, 200000);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0);
/* Wait ~10ms */
usleep_range(10000, 25000);
@@ -423,7 +436,7 @@ static void cs8409_cs42l42_reg_setup(struct hda_codec *codec)
mutex_lock(&spec->cs8409_i2c_mux);
for (; seq->addr; seq++)
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg);
mutex_unlock(&spec->cs8409_i2c_mux);
@@ -457,9 +470,9 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
mutex_lock(&spec->cs8409_i2c_mux);
/* Read jack detect status registers */
- reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1);
- reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1);
- reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1);
+ reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308);
+ reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124);
+ reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f);
mutex_unlock(&spec->cs8409_i2c_mux);
@@ -472,7 +485,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
mutex_lock(&spec->cs8409_i2c_mux);
/* Disable HSDET_AUTO_DONE */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF);
mutex_unlock(&spec->cs8409_i2c_mux);
type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1);
@@ -499,7 +512,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
mutex_lock(&spec->cs8409_i2c_mux);
/* Re-Enable Tip Sense Interrupt */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3);
mutex_unlock(&spec->cs8409_i2c_mux);
} else {
@@ -566,7 +579,7 @@ static int cs8409_suspend(struct hda_codec *codec)
mutex_lock(&spec->cs8409_i2c_mux);
/* Power down CS42L42 ASP/EQ/MIX/HP */
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe);
mutex_unlock(&spec->cs8409_i2c_mux);
spec->cs42l42_suspended = 1;
@@ -622,7 +635,7 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) {
/* FULL_SCALE_VOL = 0 for Warlock / Cyborg */
mutex_lock(&spec->cs8409_i2c_mux);
- cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1);
+ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01);
mutex_unlock(&spec->cs8409_i2c_mux);
/* DMIC1_MO=00b, DMIC1/2_SR=1 */
cs8409_vendor_coef_set(codec, 0x09, 0x0003);
@@ -631,11 +644,11 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec)
/* Restore Volumes after Resume */
mutex_lock(&spec->cs8409_i2c_mux);
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA,
- -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+ -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK);
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB,
- -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1);
+ -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK);
cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL,
- spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1);
+ spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK);
mutex_unlock(&spec->cs8409_i2c_mux);
cs8409_cs42l42_enable_jack_detect(codec);
@@ -741,6 +754,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix,
spec->cs42l42_hp_jack_in = 0;
spec->cs42l42_mic_jack_in = 0;
spec->cs42l42_suspended = 1;
+ spec->paged = 1;
/* Basic initial sequence for specific hw configuration */
snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h
index c2c208218e34..ee66fd0c01dc 100644
--- a/sound/pci/hda/patch_cs8409.h
+++ b/sound/pci/hda/patch_cs8409.h
@@ -283,6 +283,8 @@ struct cs8409_spec {
unsigned int i2c_clck_enabled;
unsigned int dev_addr;
struct delayed_work i2c_clk_work;
+ unsigned int paged;
+ unsigned int last_page;
/* verb exec op override */
int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
--
2.25.1
next prev parent reply other threads:[~2021-07-28 13:45 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-28 13:43 [PATCH v2 00/27] ALSA: hda/cirrus: Split generic cirrus HDA codecs and CS8490 bridge into separate modules Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 01/27] ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module Vitaly Rodionov
2021-07-29 9:50 ` Takashi Iwai
2021-07-28 13:43 ` [PATCH v2 02/27] ALSA: hda/cs8409: Move arrays of configuration to a new file Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 03/27] ALSA: hda/cs8409: Use enums for register names and coefficients Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 04/27] ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 05/27] ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 06/27] ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 07/27] ALSA: hda/cs8409: Disable unsolicited responses during suspend Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 08/27] ALSA: hda/cs8409: Disable unsolicited response for the first boot Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 09/27] ALSA: hda/cs8409: Mask CS42L42 wake events Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 10/27] ALSA: hda/cs8409: Simplify CS42L42 jack detect Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 11/27] ALSA: hda/cs8409: Prevent I2C access during suspend time Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 12/27] ALSA: hda/cs8409: Generalize volume controls Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 13/27] ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses Vitaly Rodionov
2021-07-29 9:48 ` Takashi Iwai
2021-07-28 13:43 ` [PATCH v2 14/27] ALSA: hda/cs8409: Avoid setting the same I2C address for every access Vitaly Rodionov
2021-07-28 13:43 ` Vitaly Rodionov [this message]
2021-07-28 13:43 ` [PATCH v2 16/27] ALSA: hda/cs8409: Support i2c bulk read/write functions Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 17/27] ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions Vitaly Rodionov
2021-07-28 13:43 ` [PATCH v2 18/27] ALSA: hda/cs8409: Move codec properties to its own struct Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 20/27] ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42 Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 21/27] ALSA: hda/cs8409: Add support for dolphin Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 22/27] ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 23/27] ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42 Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 24/27] ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 25/27] ALSA: hda/cs8409: Remove unnecessary delays Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 26/27] ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend Vitaly Rodionov
2021-07-28 13:44 ` [PATCH v2 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops Vitaly Rodionov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210728134408.369396-16-vitalyr@opensource.cirrus.com \
--to=vitalyr@opensource.cirrus.com \
--cc=alsa-devel@alsa-project.org \
--cc=linux-kernel@vger.kernel.org \
--cc=patches@opensource.cirrus.com \
--cc=perex@perex.cz \
--cc=tanureal@opensource.cirrus.com \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).