summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 10:56:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 10:56:51 -0700
commit920f2ecdf6c3b3526f60fbd38c68597953cad3ee (patch)
tree18188922ba38a5c53ee8d17032eb5c46dffc7fa2 /sound/pci/hda/patch_realtek.c
parent9ced560b82606b35adb33a27012a148d418a4c1f (diff)
parentfc18282cdcba984ab89c74d7e844c10114ae0795 (diff)
downloadlinux-stable-920f2ecdf6c3b3526f60fbd38c68597953cad3ee.tar.gz
linux-stable-920f2ecdf6c3b3526f60fbd38c68597953cad3ee.tar.bz2
linux-stable-920f2ecdf6c3b3526f60fbd38c68597953cad3ee.zip
Merge tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This development cycle resulted in a fair amount of changes in both core and driver sides. The most significant change in ALSA core is about PCM. Also the support of of-graph card and the new DAPM widget for DSP are noteworthy changes in ASoC core. And there're lots of small changes splat over the tree, as you can see in diffstat. Below are a few highlights: ALSA core: - Removal of set_fs() hackery from PCM core stuff, and the code reorganization / optimization thereafter - Improved support of PCM ack ops, and a new ABI for improved control/status mmap handling - Lots of constifications in various codes ASoC core: - The support of of-graph card, which may work as a better generic device for a replacement of simple-card - New widget types intended mainly for use with DSPs ASoC drivers: - New drivers for Allwinner V3s SoCs - Ensonic ES8316 codec support - More Intel SKL and KBL works - More device support for Intel SST Atom (mostly for cheap tablets and 2-in-1 devices) - Support for Rockchip PDM controllers - Support for STM32 I2S and S/PDIF controllers - Support for ZTE AUD96P22 codecs HD-audio: - Support of new Realtek codecs (ALC215/ALC285/ALC289), more quirks for HP and Dell machines - A few more fixes for i915 component binding" * tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (418 commits) ALSA: hda - Fix unbalance of i915 module refcount ASoC: Intel: Skylake: Remove driver debugfs exit ASoC: Intel: Skylake: explicitly add the headers sst-dsp.h ALSA: hda/realtek - Remove GPIO_MASK ALSA: hda/realtek - Fix typo of pincfg for Dell quirk ALSA: pcm: add a documentation for tracepoints ALSA: atmel: ac97c: fix error return code in atmel_ac97c_probe() ALSA: x86: fix error return code in hdmi_lpe_audio_probe() ASoC: Intel: Skylake: Add support to read firmware registers ASoC: Intel: Skylake: Add sram address to sst_addr structure ASoC: Intel: Skylake: Debugfs facility to dump module config ASoC: Intel: Skylake: Add debugfs support ASoC: fix semicolon.cocci warnings ASoC: rt5645: Add quirk override by module option ASoC: rsnd: make arrays path and cmd_case static const ASoC: audio-graph-card: add widgets and routing for external amplifier support ASoC: audio-graph-card: update bindings for amplifier support ASoC: rt5665: calibration should be done before jack detection ASoC: rsnd: constify dev_pm_ops structures. ASoC: nau8825: change crosstalk-bypass property to bool type ...
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c281
1 files changed, 262 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cbeebc0a9711..cd6987b5c6d9 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -41,9 +41,6 @@
/* keep halting ALC5505 DSP, for power saving */
#define HALT_REALTEK_ALC5505
-/* for GPIO Poll */
-#define GPIO_MASK 0x03
-
/* extra amp-initialization sequence types */
enum {
ALC_INIT_NONE,
@@ -327,6 +324,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0292:
alc_update_coef_idx(codec, 0x4, 1<<15, 0);
break;
+ case 0x10ec0215:
case 0x10ec0225:
case 0x10ec0233:
case 0x10ec0255:
@@ -335,12 +333,13 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0283:
case 0x10ec0286:
case 0x10ec0288:
+ case 0x10ec0285:
case 0x10ec0295:
case 0x10ec0298:
+ case 0x10ec0289:
case 0x10ec0299:
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break;
- case 0x10ec0285:
case 0x10ec0293:
alc_update_coef_idx(codec, 0xa, 1<<13, 0);
break;
@@ -2575,18 +2574,37 @@ static int patch_alc262(struct hda_codec *codec)
* ALC268
*/
/* bind Beep switches of both NID 0x0f and 0x10 */
-static const struct hda_bind_ctls alc268_bind_beep_sw = {
- .ops = &snd_hda_bind_sw,
- .values = {
- HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
- HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
- 0
- },
-};
+static int alc268_beep_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned long pval;
+ int err;
+
+ mutex_lock(&codec->control_mutex);
+ pval = kcontrol->private_value;
+ kcontrol->private_value = (pval & ~0xff) | 0x0f;
+ err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+ if (err >= 0) {
+ kcontrol->private_value = (pval & ~0xff) | 0x10;
+ err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+ }
+ kcontrol->private_value = pval;
+ mutex_unlock(&codec->control_mutex);
+ return err;
+}
static const struct snd_kcontrol_new alc268_beep_mixer[] = {
HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
- HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Beep Playback Switch",
+ .subdevice = HDA_SUBDEV_AMP_FLAG,
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = alc268_beep_switch_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT)
+ },
{ }
};
@@ -2719,11 +2737,12 @@ enum {
ALC269_TYPE_ALC282,
ALC269_TYPE_ALC283,
ALC269_TYPE_ALC284,
- ALC269_TYPE_ALC285,
+ ALC269_TYPE_ALC293,
ALC269_TYPE_ALC286,
ALC269_TYPE_ALC298,
ALC269_TYPE_ALC255,
ALC269_TYPE_ALC256,
+ ALC269_TYPE_ALC215,
ALC269_TYPE_ALC225,
ALC269_TYPE_ALC294,
ALC269_TYPE_ALC700,
@@ -2745,7 +2764,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
case ALC269_TYPE_ALC269VC:
case ALC269_TYPE_ALC280:
case ALC269_TYPE_ALC284:
- case ALC269_TYPE_ALC285:
+ case ALC269_TYPE_ALC293:
ssids = alc269va_ssids;
break;
case ALC269_TYPE_ALC269VB:
@@ -2756,6 +2775,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
case ALC269_TYPE_ALC298:
case ALC269_TYPE_ALC255:
case ALC269_TYPE_ALC256:
+ case ALC269_TYPE_ALC215:
case ALC269_TYPE_ALC225:
case ALC269_TYPE_ALC294:
case ALC269_TYPE_ALC700:
@@ -3043,6 +3063,135 @@ static void alc283_shutup(struct hda_codec *codec)
alc_write_coef_idx(codec, 0x43, 0x9614);
}
+static void alc256_init(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
+ if (!hp_pin)
+ return;
+
+ msleep(30);
+
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+ if (hp_pin_sense)
+ msleep(2);
+
+ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+ if (hp_pin_sense)
+ msleep(85);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+
+ if (hp_pin_sense)
+ msleep(100);
+
+ alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
+ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
+}
+
+static void alc256_shutup(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+ }
+
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+ if (hp_pin_sense)
+ msleep(2);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+ if (hp_pin_sense)
+ msleep(85);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
+ alc_update_coef_idx(codec, 0x46, 0, 3 << 12); /* 3k pull low control for Headset jack. */
+
+ if (hp_pin_sense)
+ msleep(100);
+
+ alc_auto_setup_eapd(codec, false);
+ snd_hda_shutup_pins(codec);
+}
+
+static void alc_default_init(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
+ if (!hp_pin)
+ return;
+
+ msleep(30);
+
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+ if (hp_pin_sense)
+ msleep(2);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+ if (hp_pin_sense)
+ msleep(85);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+
+ if (hp_pin_sense)
+ msleep(100);
+}
+
+static void alc_default_shutup(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
+ bool hp_pin_sense;
+
+ if (!hp_pin) {
+ alc269_shutup(codec);
+ return;
+ }
+
+ hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
+
+ if (hp_pin_sense)
+ msleep(2);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+
+ if (hp_pin_sense)
+ msleep(85);
+
+ snd_hda_codec_write(codec, hp_pin, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+
+ if (hp_pin_sense)
+ msleep(100);
+
+ alc_auto_setup_eapd(codec, false);
+ snd_hda_shutup_pins(codec);
+}
+
static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
unsigned int val)
{
@@ -3754,6 +3903,16 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
UPDATE_COEF(0x4a, 3<<10, 0),
{}
};
+ static struct coef_fw coef0274[] = {
+ UPDATE_COEF(0x4a, 0x0100, 0),
+ UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
+ UPDATE_COEF(0x6b, 0xf000, 0x5000),
+ UPDATE_COEF(0x4a, 0x0010, 0),
+ UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
+ WRITE_COEF(0x45, 0x5289),
+ UPDATE_COEF(0x4a, 0x0c00, 0),
+ {}
+ };
switch (codec->core.vendor_id) {
case 0x10ec0255:
@@ -3764,6 +3923,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
alc_process_coef_fw(codec, coef0256);
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_process_coef_fw(codec, coef0274);
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_process_coef_fw(codec, coef0233);
@@ -3841,7 +4005,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
UPDATE_COEF(0x63, 3<<14, 0),
{}
};
-
+ static struct coef_fw coef0274[] = {
+ UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
+ UPDATE_COEF(0x4a, 0x0010, 0),
+ UPDATE_COEF(0x6b, 0xf000, 0),
+ {}
+ };
switch (codec->core.vendor_id) {
case 0x10ec0255:
@@ -3851,6 +4020,14 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
alc_process_coef_fw(codec, coef0255);
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_write_coef_idx(codec, 0x45, 0x4689);
+ snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+ alc_process_coef_fw(codec, coef0274);
+ snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_write_coef_idx(codec, 0x45, 0xc429);
@@ -3948,6 +4125,13 @@ static void alc_headset_mode_default(struct hda_codec *codec)
WRITE_COEF(0xb7, 0x802b),
{}
};
+ static struct coef_fw coef0274[] = {
+ WRITE_COEF(0x45, 0x4289),
+ UPDATE_COEF(0x4a, 0x0010, 0x0010),
+ UPDATE_COEF(0x6b, 0x0f00, 0),
+ UPDATE_COEF(0x49, 0x0300, 0x0300),
+ {}
+ };
switch (codec->core.vendor_id) {
case 0x10ec0225:
@@ -3959,6 +4143,11 @@ static void alc_headset_mode_default(struct hda_codec *codec)
case 0x10ec0256:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_process_coef_fw(codec, coef0274);
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_process_coef_fw(codec, coef0233);
@@ -4044,6 +4233,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_write_coef_idx(codec, 0x45, 0xd689);
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_process_coef_fw(codec, coef0233);
@@ -4138,6 +4332,11 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_write_coef_idx(codec, 0x45, 0xe689);
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_process_coef_fw(codec, coef0233);
@@ -4201,6 +4400,13 @@ static void alc_determine_headset_type(struct hda_codec *codec)
UPDATE_COEF(0x49, 1<<8, 1<<8),
{}
};
+ static struct coef_fw coef0274[] = {
+ UPDATE_COEF(0x4a, 0x0010, 0),
+ UPDATE_COEF(0x4a, 0x8000, 0),
+ WRITE_COEF(0x45, 0xd289),
+ UPDATE_COEF(0x49, 0x0300, 0x0300),
+ {}
+ };
switch (codec->core.vendor_id) {
case 0x10ec0255:
@@ -4210,6 +4416,14 @@ static void alc_determine_headset_type(struct hda_codec *codec)
val = alc_read_coef_idx(codec, 0x46);
is_ctia = (val & 0x0070) == 0x0070;
break;
+ case 0x10ec0234:
+ case 0x10ec0274:
+ case 0x10ec0294:
+ alc_process_coef_fw(codec, coef0274);
+ msleep(80);
+ val = alc_read_coef_idx(codec, 0x46);
+ is_ctia = (val & 0x00f0) == 0x00f0;
+ break;
case 0x10ec0233:
case 0x10ec0283:
alc_write_coef_idx(codec, 0x45, 0xd029);
@@ -4892,6 +5106,7 @@ enum {
ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
+ ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
ALC269_FIXUP_HEADSET_MODE,
ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
ALC269_FIXUP_ASPIRE_HEADSET_MIC,
@@ -5192,6 +5407,16 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
},
+ [ALC269_FIXUP_DELL4_MIC_NO_PRESENCE] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+ { 0x1b, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC269_FIXUP_HEADSET_MODE
+ },
[ALC269_FIXUP_HEADSET_MODE] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode,
@@ -6322,6 +6547,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x17, 0x90170110},
{0x1a, 0x03011020},
{0x21, 0x03211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0299, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+ ALC225_STANDARD_PINS,
+ {0x12, 0xb7a60130},
+ {0x13, 0xb8a61140},
+ {0x17, 0x90170110}),
{}
};
@@ -6384,7 +6614,8 @@ static int patch_alc269(struct hda_codec *codec)
codec->patch_ops.suspend = alc269_suspend;
codec->patch_ops.resume = alc269_resume;
#endif
- spec->shutup = alc269_shutup;
+ spec->shutup = alc_default_shutup;
+ spec->init_hook = alc_default_init;
snd_hda_pick_fixup(codec, alc269_fixup_models,
alc269_fixup_tbl, alc269_fixups);
@@ -6424,6 +6655,7 @@ static int patch_alc269(struct hda_codec *codec)
}
if (err < 0)
goto error;
+ spec->shutup = alc269_shutup;
spec->init_hook = alc269_fill_coef;
alc269_fill_coef(codec);
break;
@@ -6447,9 +6679,8 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0292:
spec->codec_variant = ALC269_TYPE_ALC284;
break;
- case 0x10ec0285:
case 0x10ec0293:
- spec->codec_variant = ALC269_TYPE_ALC285;
+ spec->codec_variant = ALC269_TYPE_ALC293;
break;
case 0x10ec0286:
case 0x10ec0288:
@@ -6464,9 +6695,17 @@ static int patch_alc269(struct hda_codec *codec)
break;
case 0x10ec0256:
spec->codec_variant = ALC269_TYPE_ALC256;
+ spec->shutup = alc256_shutup;
+ spec->init_hook = alc256_init;
spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
break;
+ case 0x10ec0215:
+ case 0x10ec0285:
+ case 0x10ec0289:
+ spec->codec_variant = ALC269_TYPE_ALC215;
+ spec->gen.mixer_nid = 0;
+ break;
case 0x10ec0225:
case 0x10ec0295:
spec->codec_variant = ALC269_TYPE_ALC225;
@@ -6479,6 +6718,8 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0274:
case 0x10ec0294:
spec->codec_variant = ALC269_TYPE_ALC294;
+ spec->gen.mixer_nid = 0; /* ALC2x4 does not have any loopback mixer path */
+ alc_update_coef_idx(codec, 0x6b, 0x0018, (1<<4) | (1<<3)); /* UAJ MIC Vref control by verb */
break;
case 0x10ec0700:
case 0x10ec0701:
@@ -7495,6 +7736,7 @@ static int patch_alc680(struct hda_codec *codec)
* patch entries
*/
static const struct hda_device_id snd_hda_id_realtek[] = {
+ HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
@@ -7520,6 +7762,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
+ HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),