Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
84a3bd06
Commit
84a3bd06
authored
Dec 12, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda' into for-linus
parents
f52d7a43
52dc4386
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
175 additions
and
57 deletions
+175
-57
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+5
-0
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+2
-1
sound/pci/hda/hda_proc.c
sound/pci/hda/hda_proc.c
+6
-1
sound/pci/hda/patch_intelhdmi.c
sound/pci/hda/patch_intelhdmi.c
+86
-28
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+76
-27
No files found.
sound/pci/hda/hda_codec.h
View file @
84a3bd06
...
...
@@ -255,9 +255,13 @@ enum {
* in HD-audio specification
*/
#define AC_PINCAP_HDMI (1<<7)
/* HDMI pin */
#define AC_PINCAP_DP (1<<24)
/* DisplayPort pin, can
* coexist with AC_PINCAP_HDMI
*/
#define AC_PINCAP_VREF (0x37<<8)
#define AC_PINCAP_VREF_SHIFT 8
#define AC_PINCAP_EAPD (1<<16)
/* EAPD capable */
#define AC_PINCAP_HBR (1<<27)
/* High Bit Rate */
/* Vref status (used in pin cap) */
#define AC_PINCAP_VREF_HIZ (1<<0)
/* Hi-Z */
#define AC_PINCAP_VREF_50 (1<<1)
/* 50% */
...
...
@@ -635,6 +639,7 @@ struct hda_bus {
unsigned
int
rirb_error
:
1
;
/* error in codec communication */
unsigned
int
response_reset
:
1
;
/* controller was reset */
unsigned
int
in_reset
:
1
;
/* during reset operation */
unsigned
int
power_keep_link_on
:
1
;
/* don't power off HDA link */
};
/*
...
...
sound/pci/hda/hda_intel.c
View file @
84a3bd06
...
...
@@ -2082,7 +2082,8 @@ static void azx_power_notify(struct hda_bus *bus)
}
if
(
power_on
)
azx_init_chip
(
chip
);
else
if
(
chip
->
running
&&
power_save_controller
)
else
if
(
chip
->
running
&&
power_save_controller
&&
!
bus
->
power_keep_link_on
)
azx_stop_chip
(
chip
);
}
#endif
/* CONFIG_SND_HDA_POWER_SAVE */
...
...
sound/pci/hda/hda_proc.c
View file @
84a3bd06
...
...
@@ -240,9 +240,14 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
/* Realtek uses this bit as a different meaning */
if
((
codec
->
vendor_id
>>
16
)
==
0x10ec
)
snd_iprintf
(
buffer
,
" R/L"
);
else
else
{
if
(
caps
&
AC_PINCAP_HBR
)
snd_iprintf
(
buffer
,
" HBR"
);
snd_iprintf
(
buffer
,
" HDMI"
);
}
}
if
(
caps
&
AC_PINCAP_DP
)
snd_iprintf
(
buffer
,
" DP"
);
if
(
caps
&
AC_PINCAP_TRIG_REQ
)
snd_iprintf
(
buffer
,
" Trigger"
);
if
(
caps
&
AC_PINCAP_IMP_SENSE
)
...
...
sound/pci/hda/patch_intelhdmi.c
View file @
84a3bd06
...
...
@@ -145,6 +145,42 @@ struct cea_channel_speaker_allocation {
int
spk_mask
;
};
/*
* ALSA sequence is:
*
* surround40 surround41 surround50 surround51 surround71
* ch0 front left = = = =
* ch1 front right = = = =
* ch2 rear left = = = =
* ch3 rear right = = = =
* ch4 LFE center center center
* ch5 LFE LFE
* ch6 side left
* ch7 side right
*
* surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
*/
static
int
hdmi_channel_mapping
[
0x32
][
8
]
=
{
/* stereo */
[
0x00
]
=
{
0x00
,
0x11
,
0xf2
,
0xf3
,
0xf4
,
0xf5
,
0xf6
,
0xf7
},
/* 2.1 */
[
0x01
]
=
{
0x00
,
0x11
,
0x22
,
0xf3
,
0xf4
,
0xf5
,
0xf6
,
0xf7
},
/* Dolby Surround */
[
0x02
]
=
{
0x00
,
0x11
,
0x23
,
0xf2
,
0xf4
,
0xf5
,
0xf6
,
0xf7
},
/* surround40 */
[
0x08
]
=
{
0x00
,
0x11
,
0x24
,
0x35
,
0xf3
,
0xf2
,
0xf6
,
0xf7
},
/* 4ch */
[
0x03
]
=
{
0x00
,
0x11
,
0x23
,
0x32
,
0x44
,
0xf5
,
0xf6
,
0xf7
},
/* surround41 */
[
0x09
]
=
{
0x00
,
0x11
,
0x24
,
0x34
,
0x43
,
0xf2
,
0xf6
,
0xf7
},
/* surround50 */
[
0x0a
]
=
{
0x00
,
0x11
,
0x24
,
0x35
,
0x43
,
0xf2
,
0xf6
,
0xf7
},
/* surround51 */
[
0x0b
]
=
{
0x00
,
0x11
,
0x24
,
0x35
,
0x43
,
0x52
,
0xf6
,
0xf7
},
/* 7.1 */
[
0x13
]
=
{
0x00
,
0x11
,
0x26
,
0x37
,
0x43
,
0x52
,
0x64
,
0x75
},
};
/*
* This is an ordered list!
*
...
...
@@ -152,32 +188,36 @@ struct cea_channel_speaker_allocation {
* hdmi_setup_channel_allocation().
*/
static
struct
cea_channel_speaker_allocation
channel_allocations
[]
=
{
/* channel:
8 7 6 5 4 3 2 1
*/
/* channel:
7 6 5 4 3 2 1 0
*/
{
.
ca_index
=
0x00
,
.
speakers
=
{
0
,
0
,
0
,
0
,
0
,
0
,
FR
,
FL
}
},
/* 2.1 */
{
.
ca_index
=
0x01
,
.
speakers
=
{
0
,
0
,
0
,
0
,
0
,
LFE
,
FR
,
FL
}
},
/* Dolby Surround */
{
.
ca_index
=
0x02
,
.
speakers
=
{
0
,
0
,
0
,
0
,
FC
,
0
,
FR
,
FL
}
},
/* surround40 */
{
.
ca_index
=
0x08
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
0
,
0
,
FR
,
FL
}
},
/* surround41 */
{
.
ca_index
=
0x09
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
0
,
LFE
,
FR
,
FL
}
},
/* surround50 */
{
.
ca_index
=
0x0a
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
FC
,
0
,
FR
,
FL
}
},
/* surround51 */
{
.
ca_index
=
0x0b
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
/* 6.1 */
{
.
ca_index
=
0x0f
,
.
speakers
=
{
0
,
RC
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
/* surround71 */
{
.
ca_index
=
0x13
,
.
speakers
=
{
RRC
,
RLC
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x03
,
.
speakers
=
{
0
,
0
,
0
,
0
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x04
,
.
speakers
=
{
0
,
0
,
0
,
RC
,
0
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x05
,
.
speakers
=
{
0
,
0
,
0
,
RC
,
0
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x06
,
.
speakers
=
{
0
,
0
,
0
,
RC
,
FC
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x07
,
.
speakers
=
{
0
,
0
,
0
,
RC
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x08
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
0
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x09
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
0
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x0a
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
FC
,
0
,
FR
,
FL
}
},
/* 5.1 */
{
.
ca_index
=
0x0b
,
.
speakers
=
{
0
,
0
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x0c
,
.
speakers
=
{
0
,
RC
,
RR
,
RL
,
0
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x0d
,
.
speakers
=
{
0
,
RC
,
RR
,
RL
,
0
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x0e
,
.
speakers
=
{
0
,
RC
,
RR
,
RL
,
FC
,
0
,
FR
,
FL
}
},
/* 6.1 */
{
.
ca_index
=
0x0f
,
.
speakers
=
{
0
,
RC
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x10
,
.
speakers
=
{
RRC
,
RLC
,
RR
,
RL
,
0
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x11
,
.
speakers
=
{
RRC
,
RLC
,
RR
,
RL
,
0
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x12
,
.
speakers
=
{
RRC
,
RLC
,
RR
,
RL
,
FC
,
0
,
FR
,
FL
}
},
/* 7.1 */
{
.
ca_index
=
0x13
,
.
speakers
=
{
RRC
,
RLC
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x14
,
.
speakers
=
{
FRC
,
FLC
,
0
,
0
,
0
,
0
,
FR
,
FL
}
},
{
.
ca_index
=
0x15
,
.
speakers
=
{
FRC
,
FLC
,
0
,
0
,
0
,
LFE
,
FR
,
FL
}
},
{
.
ca_index
=
0x16
,
.
speakers
=
{
FRC
,
FLC
,
0
,
0
,
FC
,
0
,
FR
,
FL
}
},
...
...
@@ -210,7 +250,6 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
{
.
ca_index
=
0x31
,
.
speakers
=
{
FRW
,
FLW
,
RR
,
RL
,
FC
,
LFE
,
FR
,
FL
}
},
};
/*
* HDA/HDMI auto parsing
*/
...
...
@@ -344,7 +383,7 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec)
break
;
case
AC_WID_PIN
:
caps
=
snd_hda_param_read
(
codec
,
nid
,
AC_PAR_PIN_CAP
);
if
(
!
(
caps
&
AC_PINCAP_HDMI
))
if
(
!
(
caps
&
(
AC_PINCAP_HDMI
|
AC_PINCAP_DP
)
))
continue
;
if
(
intel_hdmi_add_pin
(
codec
,
nid
)
<
0
)
return
-
EINVAL
;
...
...
@@ -352,6 +391,17 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec)
}
}
/*
* G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
* can be lost and presence sense verb will become inaccurate if the
* HDA link is powered off at hot plug or hw initialization time.
*/
#ifdef CONFIG_SND_HDA_POWER_SAVE
if
(
!
(
snd_hda_param_read
(
codec
,
codec
->
afg
,
AC_PAR_POWER_STATE
)
&
AC_PWRST_EPSS
))
codec
->
bus
->
power_keep_link_on
=
1
;
#endif
return
0
;
}
...
...
@@ -436,14 +486,15 @@ static void hdmi_set_channel_count(struct hda_codec *codec,
AC_VERB_SET_CVT_CHAN_COUNT
,
chs
-
1
);
}
static
void
hdmi_debug_channel_mapping
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
static
void
hdmi_debug_channel_mapping
(
struct
hda_codec
*
codec
,
hda_nid_t
pin_nid
)
{
#ifdef CONFIG_SND_DEBUG_VERBOSE
int
i
;
int
slot
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
slot
=
snd_hda_codec_read
(
codec
,
nid
,
0
,
slot
=
snd_hda_codec_read
(
codec
,
pin_
nid
,
0
,
AC_VERB_GET_HDMI_CHAN_SLOT
,
i
);
printk
(
KERN_DEBUG
"HDMI: ASP channel %d => slot %d
\n
"
,
slot
>>
4
,
slot
&
0xf
);
...
...
@@ -619,25 +670,32 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
return
ai
->
CA
;
}
static
void
hdmi_setup_channel_mapping
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
static
void
hdmi_setup_channel_mapping
(
struct
hda_codec
*
codec
,
hda_nid_t
pin_nid
,
struct
hdmi_audio_infoframe
*
ai
)
{
int
i
;
int
ca
=
ai
->
CA
;
int
err
;
if
(
!
ai
->
CA
)
return
;
/*
* TODO: adjust channel mapping if necessary
* ALSA sequence is front/surr/clfe/side?
*/
if
(
hdmi_channel_mapping
[
ca
][
1
]
==
0
)
{
for
(
i
=
0
;
i
<
channel_allocations
[
ca
].
channels
;
i
++
)
hdmi_channel_mapping
[
ca
][
i
]
=
i
|
(
i
<<
4
);
for
(;
i
<
8
;
i
++
)
hdmi_channel_mapping
[
ca
][
i
]
=
0xf
|
(
i
<<
4
);
}
for
(
i
=
0
;
i
<
8
;
i
++
)
snd_hda_codec_write
(
codec
,
nid
,
0
,
AC_VERB_SET_HDMI_CHAN_SLOT
,
(
i
<<
4
)
|
i
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
err
=
snd_hda_codec_write
(
codec
,
pin_nid
,
0
,
AC_VERB_SET_HDMI_CHAN_SLOT
,
hdmi_channel_mapping
[
ca
][
i
]);
if
(
err
)
{
snd_printdd
(
KERN_INFO
"HDMI: channel mapping failed
\n
"
);
break
;
}
}
hdmi_debug_channel_mapping
(
codec
,
nid
);
hdmi_debug_channel_mapping
(
codec
,
pin_
nid
);
}
static
bool
hdmi_infoframe_uptodate
(
struct
hda_codec
*
codec
,
hda_nid_t
pin_nid
,
...
...
@@ -676,7 +734,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
};
hdmi_setup_channel_allocation
(
codec
,
nid
,
&
ai
);
hdmi_setup_channel_mapping
(
codec
,
nid
,
&
ai
);
for
(
i
=
0
;
i
<
spec
->
num_pins
;
i
++
)
{
if
(
spec
->
pin_cvt
[
i
]
!=
nid
)
...
...
@@ -686,6 +743,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
pin_nid
=
spec
->
pin
[
i
];
if
(
!
hdmi_infoframe_uptodate
(
codec
,
pin_nid
,
&
ai
))
{
hdmi_setup_channel_mapping
(
codec
,
pin_nid
,
&
ai
);
hdmi_stop_infoframe_trans
(
codec
,
pin_nid
);
hdmi_fill_audio_infoframe
(
codec
,
pin_nid
,
&
ai
);
hdmi_start_infoframe_trans
(
codec
,
pin_nid
);
...
...
sound/pci/hda/patch_sigmatel.c
View file @
84a3bd06
...
...
@@ -209,6 +209,7 @@ struct sigmatel_spec {
unsigned
int
gpio_data
;
unsigned
int
gpio_mute
;
unsigned
int
gpio_led
;
unsigned
int
gpio_led_polarity
;
/* stream */
unsigned
int
stream_delay
;
...
...
@@ -1538,6 +1539,13 @@ static unsigned int alienware_m17x_pin_configs[13] = {
0x904601b0
,
};
static
unsigned
int
intel_dg45id_pin_configs
[
14
]
=
{
0x02214230
,
0x02A19240
,
0x01013214
,
0x01014210
,
0x01A19250
,
0x01011212
,
0x01016211
,
0x40f000f0
,
0x40f000f0
,
0x40f000f0
,
0x40f000f0
,
0x014510A0
,
0x074510B0
,
0x40f000f0
};
static
unsigned
int
*
stac92hd73xx_brd_tbl
[
STAC_92HD73XX_MODELS
]
=
{
[
STAC_92HD73XX_REF
]
=
ref92hd73xx_pin_configs
,
[
STAC_DELL_M6_AMIC
]
=
dell_m6_pin_configs
,
...
...
@@ -1545,6 +1553,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
[
STAC_DELL_M6_BOTH
]
=
dell_m6_pin_configs
,
[
STAC_DELL_EQ
]
=
dell_m6_pin_configs
,
[
STAC_ALIENWARE_M17X
]
=
alienware_m17x_pin_configs
,
[
STAC_92HD73XX_INTEL
]
=
intel_dg45id_pin_configs
,
};
static
const
char
*
stac92hd73xx_models
[
STAC_92HD73XX_MODELS
]
=
{
...
...
@@ -4724,13 +4733,61 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
}
}
static
int
hp_bseries_system
(
u32
subsystem_id
)
/*
* This method searches for the mute LED GPIO configuration
* provided as OEM string in SMBIOS. The format of that string
* is HP_Mute_LED_P_G or HP_Mute_LED_P
* where P can be 0 or 1 and defines mute LED GPIO control state (low/high)
* that corresponds to the NOT muted state of the master volume
* and G is the index of the GPIO to use as the mute LED control (0..9)
* If _G portion is missing it is assigned based on the codec ID
*
* So, HP B-series like systems may have HP_Mute_LED_0 (current models)
* or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings
*/
static
int
find_mute_led_gpio
(
struct
hda_codec
*
codec
)
{
struct
sigmatel_spec
*
spec
=
codec
->
spec
;
const
struct
dmi_device
*
dev
=
NULL
;
if
((
codec
->
subsystem_id
>>
16
)
==
PCI_VENDOR_ID_HP
)
{
while
((
dev
=
dmi_find_device
(
DMI_DEV_TYPE_OEM_STRING
,
NULL
,
dev
)))
{
if
(
sscanf
(
dev
->
name
,
"HP_Mute_LED_%d_%d"
,
&
spec
->
gpio_led_polarity
,
&
spec
->
gpio_led
)
==
2
)
{
spec
->
gpio_led
=
1
<<
spec
->
gpio_led
;
return
1
;
}
if
(
sscanf
(
dev
->
name
,
"HP_Mute_LED_%d"
,
&
spec
->
gpio_led_polarity
)
==
1
)
{
switch
(
codec
->
vendor_id
)
{
case
0x111d7608
:
/* GPIO 0 */
spec
->
gpio_led
=
0x01
;
return
1
;
case
0x111d7600
:
case
0x111d7601
:
case
0x111d7602
:
case
0x111d7603
:
/* GPIO 3 */
spec
->
gpio_led
=
0x08
;
return
1
;
}
}
}
}
return
0
;
}
static
int
hp_blike_system
(
u32
subsystem_id
)
{
switch
(
subsystem_id
)
{
case
0x103c307e
:
case
0x103c307f
:
case
0x103c3080
:
case
0x103c3081
:
case
0x103c1520
:
case
0x103c1521
:
case
0x103c1523
:
case
0x103c1524
:
case
0x103c1525
:
case
0x103c1722
:
case
0x103c1723
:
case
0x103c1724
:
...
...
@@ -4739,6 +4796,14 @@ static int hp_bseries_system(u32 subsystem_id)
case
0x103c1727
:
case
0x103c1728
:
case
0x103c1729
:
case
0x103c172a
:
case
0x103c172b
:
case
0x103c307e
:
case
0x103c307f
:
case
0x103c3080
:
case
0x103c3081
:
case
0x103c7007
:
case
0x103c7008
:
return
1
;
}
return
0
;
...
...
@@ -4833,7 +4898,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
else
spec
->
gpio_data
|=
spec
->
gpio_led
;
/* white */
if
(
hp_bseries_system
(
codec
->
subsystem_id
)
)
{
if
(
!
spec
->
gpio_led_polarity
)
{
/* LED state is inverted on these systems */
spec
->
gpio_data
^=
spec
->
gpio_led
;
}
...
...
@@ -5526,7 +5591,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
break
;
}
if
(
hp_b
series
_system
(
codec
->
subsystem_id
))
{
if
(
hp_b
like
_system
(
codec
->
subsystem_id
))
{
pin_cfg
=
snd_hda_codec_get_pincfg
(
codec
,
0x0f
);
if
(
get_defcfg_device
(
pin_cfg
)
==
AC_JACK_LINE_OUT
||
get_defcfg_device
(
pin_cfg
)
==
AC_JACK_SPEAKER
||
...
...
@@ -5544,26 +5609,10 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
}
}
if
((
codec
->
subsystem_id
>>
16
)
==
PCI_VENDOR_ID_HP
)
{
const
struct
dmi_device
*
dev
=
NULL
;
while
((
dev
=
dmi_find_device
(
DMI_DEV_TYPE_OEM_STRING
,
NULL
,
dev
)))
{
if
(
strcmp
(
dev
->
name
,
"HP_Mute_LED_1"
))
{
switch
(
codec
->
vendor_id
)
{
case
0x111d7608
:
spec
->
gpio_led
=
0x01
;
break
;
case
0x111d7600
:
case
0x111d7601
:
case
0x111d7602
:
case
0x111d7603
:
spec
->
gpio_led
=
0x08
;
break
;
}
break
;
}
}
}
if
(
find_mute_led_gpio
(
codec
))
snd_printd
(
"mute LED gpio %d polarity %d
\n
"
,
spec
->
gpio_led
,
spec
->
gpio_led_polarity
);
#ifdef CONFIG_SND_HDA_POWER_SAVE
if
(
spec
->
gpio_led
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment