@@ -1854,6 +1854,163 @@ static void alc298_samsung_v2_init_amps(struct hda_codec *codec,
18541854 spec -> gen .pcm_playback_hook = alc298_samsung_v2_playback_hook ;
18551855}
18561856
1857+ /* LG Gram Style 14: program vendor coef sequence used by HDA-verb workaround */
1858+ struct alc298_lg_gram_style_seq {
1859+ unsigned short verb ;
1860+ unsigned short idx ;
1861+ unsigned short val ;
1862+ };
1863+
1864+ static void alc298_lg_gram_style_coef_write (struct hda_codec * codec ,
1865+ unsigned int verb ,
1866+ unsigned int idx ,
1867+ unsigned int val )
1868+ {
1869+ snd_hda_codec_write (codec , 0x20 , 0 , AC_VERB_SET_COEF_INDEX , 0x23 );
1870+ snd_hda_codec_write (codec , 0x20 , 0 , verb , idx );
1871+ snd_hda_codec_write (codec , 0x20 , 0 , AC_VERB_SET_PROC_COEF , 0x00 );
1872+ snd_hda_codec_write (codec , 0x20 , 0 , AC_VERB_SET_PROC_COEF , val );
1873+ snd_hda_codec_write (codec , 0x20 , 0 , AC_VERB_SET_PROC_COEF , 0xb011 );
1874+ }
1875+
1876+ static void alc298_lg_gram_style_run_seq (struct hda_codec * codec ,
1877+ const struct alc298_lg_gram_style_seq * seq ,
1878+ int seq_size )
1879+ {
1880+ int i ;
1881+
1882+ for (i = 0 ; i < seq_size ; i ++ )
1883+ alc298_lg_gram_style_coef_write (codec , seq [i ].verb ,
1884+ seq [i ].idx , seq [i ].val );
1885+ }
1886+
1887+ /* Coef sequences derived from the HDA-verb workaround for this model. */
1888+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_preinit_seq [] = {
1889+ { 0x420 , 0x00 , 0x01 },
1890+ };
1891+
1892+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_disable_seq [] = {
1893+ { 0x423 , 0xff , 0x00 },
1894+ { 0x420 , 0x3a , 0x80 },
1895+ };
1896+
1897+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_enable_seq [] = {
1898+ { 0x420 , 0x3a , 0x81 },
1899+ { 0x423 , 0xff , 0x01 },
1900+ };
1901+
1902+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_38 [] = {
1903+ { 0x423 , 0xe1 , 0x00 }, { 0x420 , 0x12 , 0x6f }, { 0x420 , 0x14 , 0x00 },
1904+ { 0x420 , 0x1b , 0x01 }, { 0x420 , 0x1d , 0x01 }, { 0x420 , 0x1f , 0xfe },
1905+ { 0x420 , 0x21 , 0x00 }, { 0x420 , 0x22 , 0x10 }, { 0x420 , 0x3d , 0x05 },
1906+ { 0x420 , 0x3f , 0x03 }, { 0x420 , 0x50 , 0x2c }, { 0x420 , 0x76 , 0x0e },
1907+ { 0x420 , 0x7c , 0x4a }, { 0x420 , 0x81 , 0x03 }, { 0x423 , 0x99 , 0x03 },
1908+ { 0x423 , 0xa4 , 0xb5 }, { 0x423 , 0xa5 , 0x01 }, { 0x423 , 0xba , 0x94 },
1909+ };
1910+
1911+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_39 [] = {
1912+ { 0x423 , 0xe1 , 0x00 }, { 0x420 , 0x12 , 0x6f }, { 0x420 , 0x14 , 0x00 },
1913+ { 0x420 , 0x1b , 0x02 }, { 0x420 , 0x1d , 0x02 }, { 0x420 , 0x1f , 0xfd },
1914+ { 0x420 , 0x21 , 0x01 }, { 0x420 , 0x22 , 0x10 }, { 0x420 , 0x3d , 0x05 },
1915+ { 0x420 , 0x3f , 0x03 }, { 0x420 , 0x50 , 0x2c }, { 0x420 , 0x76 , 0x0e },
1916+ { 0x420 , 0x7c , 0x4a }, { 0x420 , 0x81 , 0x03 }, { 0x423 , 0x99 , 0x03 },
1917+ { 0x423 , 0xa4 , 0xb5 }, { 0x423 , 0xa5 , 0x01 }, { 0x423 , 0xba , 0x94 },
1918+ };
1919+
1920+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3c [] = {
1921+ { 0x423 , 0xe1 , 0x00 }, { 0x420 , 0x12 , 0x6f }, { 0x420 , 0x14 , 0x00 },
1922+ { 0x420 , 0x1b , 0x01 }, { 0x420 , 0x1d , 0x01 }, { 0x420 , 0x1f , 0xfe },
1923+ { 0x420 , 0x21 , 0x00 }, { 0x420 , 0x22 , 0x10 }, { 0x420 , 0x3d , 0x05 },
1924+ { 0x420 , 0x3f , 0x03 }, { 0x420 , 0x50 , 0x2c }, { 0x420 , 0x76 , 0x0e },
1925+ { 0x420 , 0x7c , 0x4a }, { 0x420 , 0x81 , 0x03 }, { 0x423 , 0xba , 0x8d },
1926+ };
1927+
1928+ static const struct alc298_lg_gram_style_seq alc298_lg_gram_style_init_seq_3d [] = {
1929+ { 0x423 , 0xe1 , 0x00 }, { 0x420 , 0x12 , 0x6f }, { 0x420 , 0x14 , 0x00 },
1930+ { 0x420 , 0x1b , 0x02 }, { 0x420 , 0x1d , 0x02 }, { 0x420 , 0x1f , 0xfd },
1931+ { 0x420 , 0x21 , 0x01 }, { 0x420 , 0x22 , 0x10 }, { 0x420 , 0x3d , 0x05 },
1932+ { 0x420 , 0x3f , 0x03 }, { 0x420 , 0x50 , 0x2c }, { 0x420 , 0x76 , 0x0e },
1933+ { 0x420 , 0x7c , 0x4a }, { 0x420 , 0x81 , 0x03 }, { 0x423 , 0xba , 0x8d },
1934+ };
1935+
1936+ struct alc298_lg_gram_style_amp_desc {
1937+ unsigned char nid ;
1938+ const struct alc298_lg_gram_style_seq * init_seq ;
1939+ int init_seq_size ;
1940+ };
1941+
1942+ static const struct alc298_lg_gram_style_amp_desc alc298_lg_gram_style_amps [] = {
1943+ { 0x38 , alc298_lg_gram_style_init_seq_38 ,
1944+ ARRAY_SIZE (alc298_lg_gram_style_init_seq_38 ) },
1945+ { 0x39 , alc298_lg_gram_style_init_seq_39 ,
1946+ ARRAY_SIZE (alc298_lg_gram_style_init_seq_39 ) },
1947+ { 0x3c , alc298_lg_gram_style_init_seq_3c ,
1948+ ARRAY_SIZE (alc298_lg_gram_style_init_seq_3c ) },
1949+ { 0x3d , alc298_lg_gram_style_init_seq_3d ,
1950+ ARRAY_SIZE (alc298_lg_gram_style_init_seq_3d ) },
1951+ };
1952+
1953+ static void alc298_lg_gram_style_enable_amps (struct hda_codec * codec )
1954+ {
1955+ struct alc_spec * spec = codec -> spec ;
1956+ int i ;
1957+
1958+ for (i = 0 ; i < spec -> num_speaker_amps ; i ++ ) {
1959+ alc_write_coef_idx (codec , 0x22 , alc298_lg_gram_style_amps [i ].nid );
1960+ alc298_lg_gram_style_run_seq (codec ,
1961+ alc298_lg_gram_style_enable_seq ,
1962+ ARRAY_SIZE (alc298_lg_gram_style_enable_seq ));
1963+ }
1964+ }
1965+
1966+ static void alc298_lg_gram_style_disable_amps (struct hda_codec * codec )
1967+ {
1968+ struct alc_spec * spec = codec -> spec ;
1969+ int i ;
1970+
1971+ for (i = 0 ; i < spec -> num_speaker_amps ; i ++ ) {
1972+ alc_write_coef_idx (codec , 0x22 , alc298_lg_gram_style_amps [i ].nid );
1973+ alc298_lg_gram_style_run_seq (codec ,
1974+ alc298_lg_gram_style_disable_seq ,
1975+ ARRAY_SIZE (alc298_lg_gram_style_disable_seq ));
1976+ }
1977+ }
1978+
1979+ static void alc298_lg_gram_style_playback_hook (struct hda_pcm_stream * hinfo ,
1980+ struct hda_codec * codec ,
1981+ struct snd_pcm_substream * substream ,
1982+ int action )
1983+ {
1984+ if (action == HDA_GEN_PCM_ACT_OPEN )
1985+ alc298_lg_gram_style_enable_amps (codec );
1986+ if (action == HDA_GEN_PCM_ACT_CLOSE )
1987+ alc298_lg_gram_style_disable_amps (codec );
1988+ }
1989+
1990+ static void alc298_lg_gram_style_init_amps (struct hda_codec * codec )
1991+ {
1992+ struct alc_spec * spec = codec -> spec ;
1993+ int i ;
1994+
1995+ spec -> num_speaker_amps = ARRAY_SIZE (alc298_lg_gram_style_amps );
1996+
1997+ for (i = 0 ; i < spec -> num_speaker_amps ; i ++ ) {
1998+ alc_write_coef_idx (codec , 0x22 , alc298_lg_gram_style_amps [i ].nid );
1999+ alc298_lg_gram_style_run_seq (codec ,
2000+ alc298_lg_gram_style_preinit_seq ,
2001+ ARRAY_SIZE (alc298_lg_gram_style_preinit_seq ));
2002+ alc298_lg_gram_style_run_seq (codec ,
2003+ alc298_lg_gram_style_disable_seq ,
2004+ ARRAY_SIZE (alc298_lg_gram_style_disable_seq ));
2005+ alc298_lg_gram_style_run_seq (codec ,
2006+ alc298_lg_gram_style_amps [i ].init_seq ,
2007+ alc298_lg_gram_style_amps [i ].init_seq_size );
2008+ alc_write_coef_idx (codec , 0x89 , 0x0 );
2009+ }
2010+
2011+ spec -> gen .pcm_playback_hook = alc298_lg_gram_style_playback_hook ;
2012+ }
2013+
18572014static void alc298_fixup_samsung_amp_v2_2_amps (struct hda_codec * codec ,
18582015 const struct hda_fixup * fix , int action )
18592016{
@@ -1868,6 +2025,13 @@ static void alc298_fixup_samsung_amp_v2_4_amps(struct hda_codec *codec,
18682025 alc298_samsung_v2_init_amps (codec , 4 );
18692026}
18702027
2028+ static void alc298_fixup_lg_gram_style_14 (struct hda_codec * codec ,
2029+ const struct hda_fixup * fix , int action )
2030+ {
2031+ if (action == HDA_FIXUP_ACT_PROBE )
2032+ alc298_lg_gram_style_init_amps (codec );
2033+ }
2034+
18712035static void gpio2_mic_hotkey_event (struct hda_codec * codec ,
18722036 struct hda_jack_callback * event )
18732037{
@@ -3753,6 +3917,7 @@ enum {
37533917 ALC298_FIXUP_SAMSUNG_AMP ,
37543918 ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS ,
37553919 ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ,
3920+ ALC298_FIXUP_LG_GRAM_STYLE_14 ,
37563921 ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ,
37573922 ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ,
37583923 ALC295_FIXUP_ASUS_MIC_NO_PRESENCE ,
@@ -5430,6 +5595,10 @@ static const struct hda_fixup alc269_fixups[] = {
54305595 .type = HDA_FIXUP_FUNC ,
54315596 .v .func = alc298_fixup_samsung_amp_v2_4_amps
54325597 },
5598+ [ALC298_FIXUP_LG_GRAM_STYLE_14 ] = {
5599+ .type = HDA_FIXUP_FUNC ,
5600+ .v .func = alc298_fixup_lg_gram_style_14
5601+ },
54335602 [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET ] = {
54345603 .type = HDA_FIXUP_VERBS ,
54355604 .v .verbs = (const struct hda_verb []) {
@@ -7368,6 +7537,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
73687537 SND_PCI_QUIRK (0x1854 , 0x0488 , "LG gram 16 (16Z90R)" , ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),
73697538 SND_PCI_QUIRK (0x1854 , 0x0489 , "LG gram 16 (16Z90R-A)" , ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),
73707539 SND_PCI_QUIRK (0x1854 , 0x048a , "LG gram 17 (17ZD90R)" , ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS ),
7540+ SND_PCI_QUIRK (0x1854 , 0x0490 , "LG Gram Style 14 (14Z90RS)" , ALC298_FIXUP_LG_GRAM_STYLE_14 ),
73717541 SND_PCI_QUIRK (0x19e5 , 0x3204 , "Huawei MACH-WX9" , ALC256_FIXUP_HUAWEI_MACH_WX9_PINS ),
73727542 SND_PCI_QUIRK (0x19e5 , 0x320f , "Huawei WRT-WX9 " , ALC256_FIXUP_ASUS_MIC_NO_PRESENCE ),
73737543 SND_PCI_QUIRK (0x19e5 , 0x3212 , "Huawei KLV-WX9 " , ALC256_FIXUP_ACER_HEADSET_MIC ),
0 commit comments