xref: /dragonfly/sys/gnu/dev/sound/pci/hda/hda_acer_c720_patch.c (revision 536a8300c32bdf0b5bba36cfda13cadeac20ce13)
1 /*
2  * Universal Interface for Intel High Definition Audio Codec
3  *
4  * HD audio interface patch for Realtek ALC codecs
5  *
6  * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7  *                    PeiSen Hou <pshou@realtek.com.tw>
8  *                    Takashi Iwai <tiwai@suse.de>
9  *                    Jonathan Woithe <jwoithe@just42.net>
10  *
11  *  This driver is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This driver is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  *
25  * Taken from linux's patch_realtek.c
26  */
27 
28 #ifdef HAVE_KERNEL_OPTION_HEADERS
29 #include "opt_snd.h"
30 #endif
31 
32 #include <dev/sound/pcm/sound.h>
33 
34 #include <sys/ctype.h>
35 
36 #include <dev/sound/pci/hda/hdac.h>
37 #include <dev/sound/pci/hda/hdaa.h>
38 #include <dev/sound/pci/hda/hda_reg.h>
39 #include <dev/sound/pci/hda/hdaa_patches.h>
40 
41 void
hdaa_patch_direct_acer_c720(struct hdaa_devinfo * devinfo)42 hdaa_patch_direct_acer_c720(struct hdaa_devinfo *devinfo)
43 {
44           struct hdaa_widget *w;
45           device_t dev = devinfo->dev;
46           uint32_t val;
47 
48           kprintf("Acer C720 patch\n");
49 
50           /* power down control */
51           hda_write_coef_idx(dev, 0x20, 0x03, 0x0002);
52           /* FIFO and filter clock */
53           hda_write_coef_idx(dev, 0x20, 0x05, 0x0700);
54           /* DMIC control */
55           hda_write_coef_idx(dev, 0x20, 0x07, 0x0200);
56           /* Analog clock */
57           val = hda_read_coef_idx(dev, 0x20, 0x06);
58           hda_write_coef_idx(dev, 0x20, 0x06, (val & ~0x00f0) | 0x0);
59 
60           /* JD */
61           val = hda_read_coef_idx(dev, 0x20, 0x08);
62           hda_write_coef_idx(dev, 0x20, 0x08, (val & ~0xfffc) | 0x0c2c);
63           /* JD offset1 */
64           hda_write_coef_idx(dev, 0x20, 0x0a, 0xcccc);
65           /* JD offset2 */
66           hda_write_coef_idx(dev, 0x20, 0x0b, 0xcccc);
67           /* LD0/1/2/3, DAC/ADC */
68           hda_write_coef_idx(dev, 0x20, 0x0e, 0x6fc0);
69           /* JD */
70           val = hda_read_coef_idx(dev, 0x20, 0x0f);
71           hda_write_coef_idx(dev, 0x20, 0x0f, (val & ~0xf800) | 0x1000);
72 
73           /* Capless */
74           val = hda_read_coef_idx(dev, 0x20, 0x10);
75           hda_write_coef_idx(dev, 0x20, 0x10, (val & ~0xfc00) | 0x0c00);
76           /* Class D test 4 */
77           hda_write_coef_idx(dev, 0x20, 0x3a, 0x0);
78           /* IO power down directly */
79           val = hda_read_coef_idx(dev, 0x20, 0x0c);
80           hda_write_coef_idx(dev, 0x20, 0x0c, (val & ~0xfe00) | 0x0);
81           /* ANC */
82           hda_write_coef_idx(dev, 0x20, 0x22, 0xa0c0);
83           /* AGC MUX */
84           val = hda_read_coef_idx(dev, 0x53, 0x01);
85           hda_write_coef_idx(dev, 0x53, 0x01, (val & ~0x000f) | 0x0008);
86 
87           /* DAC simple content protection */
88           val = hda_read_coef_idx(dev, 0x20, 0x1d);
89           hda_write_coef_idx(dev, 0x20, 0x1d, (val & ~0x00e0) | 0x0);
90           /* ADC simple content protection */
91           val = hda_read_coef_idx(dev, 0x20, 0x1f);
92           hda_write_coef_idx(dev, 0x20, 0x1f, (val & ~0x00e0) | 0x0);
93           /* DAC ADC Zero Detection */
94           hda_write_coef_idx(dev, 0x20, 0x21, 0x8804);
95           /* PLL */
96           hda_write_coef_idx(dev, 0x20, 0x2e, 0x2902);
97           /* capless control 2 */
98           hda_write_coef_idx(dev, 0x20, 0x33, 0xa080);
99           /* capless control 3 */
100           hda_write_coef_idx(dev, 0x20, 0x34, 0x3400);
101           /* capless control 4 */
102           hda_write_coef_idx(dev, 0x20, 0x35, 0x2f3e);
103           /* capless control 5 */
104           hda_write_coef_idx(dev, 0x20, 0x36, 0x0);
105           /* class D test 2 */
106           val = hda_read_coef_idx(dev, 0x20, 0x38);
107           hda_write_coef_idx(dev, 0x20, 0x38, (val & ~0x0fff) | 0x0900);
108 
109           /* class D test 3 */
110           hda_write_coef_idx(dev, 0x20, 0x39, 0x110a);
111           /* class D test 5 */
112           val = hda_read_coef_idx(dev, 0x20, 0x3b);
113           hda_write_coef_idx(dev, 0x20, 0x3b, (val & ~0x00f8) | 0x00d8);
114           /* class D test 6 */
115           hda_write_coef_idx(dev, 0x20, 0x3c, 0x0014);
116           /* classD OCP */
117           hda_write_coef_idx(dev, 0x20, 0x3d, 0xc2ba);
118           /* classD pure DC test */
119           val = hda_read_coef_idx(dev, 0x20, 0x42);
120           hda_write_coef_idx(dev, 0x20, 0x42, (val & ~0x0f80) | 0x0);
121           /* test mode */
122           hda_write_coef_idx(dev, 0x20, 0x49, 0x0);
123           /* Class D DC enable */
124           val = hda_read_coef_idx(dev, 0x20, 0x40);
125           hda_write_coef_idx(dev, 0x20, 0x40, (val & ~0xf800) | 0x9800);
126           /* DC offset */
127           val = hda_read_coef_idx(dev, 0x20, 0x42);
128           hda_write_coef_idx(dev, 0x20, 0x42, (val & ~0xf000) | 0x2000);
129           /* Class D amp control */
130           hda_write_coef_idx(dev, 0x20, 0x37, 0xfc06);
131 
132           /* Index 0x43 direct drive HP AMP LPM Control 1 */
133           /* Headphone capless set to high power mode */
134           hda_write_coef_idx(dev, 0x20, 0x43, 0x9004);
135 
136 #if 0
137           /*
138            * This has to do with the 'mute internal speaker when
139            * ext headphone out jack is plugged' function.  nid 27
140            * comes from the special config bits (XXX currently hardwired)
141            *
142            * XXX doesn't apply to chromebook where we just have to change
143            *        the mixer selection for nid 33.
144            */
145           int dummy;
146           hda_command(dev, HDA_CMD_SET_AMP_GAIN_MUTE(0, 27, 0xb080));
147           tsleep(&dummy, 0, "hdaslp", hz / 10);
148           hda_command(dev, HDA_CMD_SET_PIN_WIDGET_CTRL(0, 27,
149                                         HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE));
150           tsleep(&dummy, 0, "hdaslp", hz / 10);
151 #endif
152 
153           /* 0x46 combo jack auto switch control 2 */
154           /* 3k pull-down control for headset jack. */
155           val = hda_read_coef_idx(dev, 0x20, 0x46);
156           hda_write_coef_idx(dev, 0x20, 0x46, val & ~(3 << 12));
157           /* headphone capless set to normal mode */
158           hda_write_coef_idx(dev, 0x20, 0x43, 0x9614);
159 
160 #if 0
161           /*
162            * Fixup chromebook (? which chromebook?)
163            */
164           /* MIC2-VREF control */
165           /* set to manual mode */
166           val = hda_read_coef_idx(dev, 0x20, 0x06);
167           hda_write_coef_idx(dev, 0x20, 0x06, val & ~0x000c);
168           /* enable line1 input control by verb */
169           val = hda_read_coef_idx(dev, 0x20, 0x1a);
170           hda_write_coef_idx(dev, 0x20, 0x1a, val | (1 << 4));
171 #endif
172 
173           /*
174            * 31-30  : port connectivity
175            * 29-21  : reserved
176            * 20               : PCBEEP input
177            * 19-16  : checksum (15:1)
178            * 15-1             : Custom
179            * 0                : Override
180            *
181            * XXX this needs code from linux patch_realtek.c alc_subsystem_id().
182            * Chromebook: 0x4015812d
183            *        bit 30    physical connection present
184            *        bit 15    if set we want the 'mute internal speaker when
185            *                  ext headphone out jack is plugged' function
186            *            bit 14:13       reserved
187            *            bit 12:11       headphone out 00: PortA, 01: PortE, 02: PortD,
188            *                                            03: Reserved (for C720 this is 0)
189            *            bit 10:8    jack location (for c720 this is 1)
190            *                                      0, 0x1b, 0x14, 0x21 - nnid 27 is jack?
191            *
192            *        bit 5:3   -> 101 (5).  ALC_INIT_DEFAULT (default ext amp ctl)
193            *        bit 0     override (is set)
194            */
195           if ((w = hdaa_widget_get(devinfo, 0x1d)) != NULL) {
196                     kprintf("WIDGET SPECIAL: %08x\n", w->wclass.pin.config);
197                     /* XXX currently in hdaa_patch_direct_acer_c720(devinfo); */
198           }
199 }
200