blob: b4f3c7295a535841b520c7066a2e8c8f5f42a41f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 *
Takashi Iwaid01ce992007-07-27 16:52:19 +02003 * hda_intel.c - Implementation of primary alsa driver code base
4 * for Intel HD Audio.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Copyright(c) 2004 Intel Corporation. All rights reserved.
7 *
8 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
9 * PeiSen Hou <pshou@realtek.com.tw>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 *
25 * CONTACTS:
26 *
27 * Matt Jared matt.jared@intel.com
28 * Andy Kopp andy.kopp@intel.com
29 * Dan Kogan dan.d.kogan@intel.com
30 *
31 * CHANGES:
32 *
33 * 2004.12.01 Major rewrite by tiwai, merged the work of pshou
34 *
35 */
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/delay.h>
38#include <linux/interrupt.h>
Randy Dunlap362775e2005-11-07 14:43:23 +010039#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/module.h>
Andrew Morton24982c52008-03-04 10:08:58 +010041#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/moduleparam.h>
43#include <linux/init.h>
44#include <linux/slab.h>
45#include <linux/pci.h>
Ingo Molnar62932df2006-01-16 16:34:20 +010046#include <linux/mutex.h>
Takashi Iwai0cbf0092008-10-29 16:18:25 +010047#include <linux/reboot.h>
Takashi Iwai27fe48d92011-09-28 17:16:09 +020048#include <linux/io.h>
49#ifdef CONFIG_X86
50/* for snoop control */
51#include <asm/pgtable.h>
52#include <asm/cacheflush.h>
53#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <sound/core.h>
55#include <sound/initval.h>
Takashi Iwai91219472012-04-26 12:13:25 +020056#include <linux/vgaarb.h>
Takashi Iwaia82d51e2012-04-26 12:23:42 +020057#include <linux/vga_switcheroo.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#include "hda_codec.h"
59
60
Takashi Iwai5aba4f82008-01-07 15:16:37 +010061static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
62static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
Rusty Russella67ff6a2011-12-15 13:49:36 +103063static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
Takashi Iwai5aba4f82008-01-07 15:16:37 +010064static char *model[SNDRV_CARDS];
65static int position_fix[SNDRV_CARDS];
Takashi Iwai5c0d7bc2008-06-10 17:53:35 +020066static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
Takashi Iwai5aba4f82008-01-07 15:16:37 +010067static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
Takashi Iwaid4d9cd032008-12-19 15:19:11 +010068static int probe_only[SNDRV_CARDS];
Rusty Russella67ff6a2011-12-15 13:49:36 +103069static bool single_cmd;
Takashi Iwai716238552009-09-28 13:14:04 +020070static int enable_msi = -1;
Takashi Iwai4ea6fbc2009-06-17 09:52:54 +020071#ifdef CONFIG_SND_HDA_PATCH_LOADER
72static char *patch[SNDRV_CARDS];
73#endif
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +010074#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai0920c9b2012-07-03 16:58:48 +020075static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +010076 CONFIG_SND_HDA_INPUT_BEEP_MODE};
77#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Takashi Iwai5aba4f82008-01-07 15:16:37 +010079module_param_array(index, int, NULL, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
Takashi Iwai5aba4f82008-01-07 15:16:37 +010081module_param_array(id, charp, NULL, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070082MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
Takashi Iwai5aba4f82008-01-07 15:16:37 +010083module_param_array(enable, bool, NULL, 0444);
84MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
85module_param_array(model, charp, NULL, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086MODULE_PARM_DESC(model, "Use the given board model.");
Takashi Iwai5aba4f82008-01-07 15:16:37 +010087module_param_array(position_fix, int, NULL, 0444);
David Henningsson4cb36312010-09-30 10:12:50 +020088MODULE_PARM_DESC(position_fix, "DMA pointer read method."
Takashi Iwaia6f2fd52012-02-28 11:58:40 +010089 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
Takashi Iwai555e2192008-06-10 17:53:34 +020090module_param_array(bdl_pos_adj, int, NULL, 0644);
91MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
Takashi Iwai5aba4f82008-01-07 15:16:37 +010092module_param_array(probe_mask, int, NULL, 0444);
Takashi Iwai606ad752005-11-24 16:03:40 +010093MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
Jaroslav Kysela079e6832010-03-26 11:16:59 +010094module_param_array(probe_only, int, NULL, 0444);
Takashi Iwaid4d9cd032008-12-19 15:19:11 +010095MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
Takashi Iwai27346162006-01-12 18:28:44 +010096module_param(single_cmd, bool, 0444);
Takashi Iwaid01ce992007-07-27 16:52:19 +020097MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
98 "(for debugging only).");
Takashi Iwaiac9ef6c2012-01-20 12:08:44 +010099module_param(enable_msi, bint, 0444);
Takashi Iwai134a11f2006-11-10 12:08:37 +0100100MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
Takashi Iwai4ea6fbc2009-06-17 09:52:54 +0200101#ifdef CONFIG_SND_HDA_PATCH_LOADER
102module_param_array(patch, charp, NULL, 0444);
103MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
104#endif
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +0100105#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai0920c9b2012-07-03 16:58:48 +0200106module_param_array(beep_mode, bool, NULL, 0444);
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +0100107MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
Takashi Iwai0920c9b2012-07-03 16:58:48 +0200108 "(0=off, 1=on) (default=1).");
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +0100109#endif
Takashi Iwai606ad752005-11-24 16:03:40 +0100110
Takashi Iwaidee1b662007-08-13 16:10:30 +0200111#ifdef CONFIG_SND_HDA_POWER_SAVE
Takashi Iwaifee2fba2008-11-27 12:43:28 +0100112static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
113module_param(power_save, int, 0644);
114MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
115 "(in second, 0 = disable).");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Takashi Iwaidee1b662007-08-13 16:10:30 +0200117/* reset the HD-audio controller in power save mode.
118 * this may give more power-saving, but will take longer time to
119 * wake up.
120 */
Rusty Russella67ff6a2011-12-15 13:49:36 +1030121static bool power_save_controller = 1;
Takashi Iwaidee1b662007-08-13 16:10:30 +0200122module_param(power_save_controller, bool, 0644);
123MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
124#endif
125
Takashi Iwai7bfe0592012-01-23 17:53:39 +0100126static int align_buffer_size = -1;
127module_param(align_buffer_size, bint, 0644);
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -0500128MODULE_PARM_DESC(align_buffer_size,
129 "Force buffer and period sizes to be multiple of 128 bytes.");
130
Takashi Iwai27fe48d92011-09-28 17:16:09 +0200131#ifdef CONFIG_X86
132static bool hda_snoop = true;
133module_param_named(snoop, hda_snoop, bool, 0444);
134MODULE_PARM_DESC(snoop, "Enable/disable snooping");
135#define azx_snoop(chip) (chip)->snoop
136#else
137#define hda_snoop true
138#define azx_snoop(chip) true
139#endif
140
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142MODULE_LICENSE("GPL");
143MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
144 "{Intel, ICH6M},"
Jason Gaston2f1b3812005-05-01 08:58:50 -0700145 "{Intel, ICH7},"
Frederick Lif5d40b32005-05-12 14:55:20 +0200146 "{Intel, ESB2},"
Jason Gastond2981392006-01-10 11:07:37 +0100147 "{Intel, ICH8},"
Jason Gastonf9cc8a82006-11-22 11:53:52 +0100148 "{Intel, ICH9},"
Jason Gastonc34f5a02008-01-29 12:38:49 +0100149 "{Intel, ICH10},"
Seth Heasleyb29c2362008-08-08 15:56:39 -0700150 "{Intel, PCH},"
Seth Heasleyd2f2fcd2010-01-12 17:03:35 -0800151 "{Intel, CPT},"
Seth Heasleyd2edeb72011-04-20 10:59:57 -0700152 "{Intel, PPT},"
Seth Heasley8bc039a2012-01-23 16:24:31 -0800153 "{Intel, LPT},"
Wang Xingchaoe926f2c2012-06-13 10:23:51 +0800154 "{Intel, HPT},"
Seth Heasleycea310e2010-09-10 16:29:56 -0700155 "{Intel, PBG},"
Tobin Davis4979bca2008-01-30 08:13:55 +0100156 "{Intel, SCH},"
Takashi Iwaifc20a562005-05-12 15:00:41 +0200157 "{ATI, SB450},"
Felix Kuehling89be83f2006-03-31 12:33:59 +0200158 "{ATI, SB600},"
Felix Kuehling778b6e12006-05-17 11:22:21 +0200159 "{ATI, RS600},"
Felix Kuehling5b15c952006-10-16 12:49:47 +0200160 "{ATI, RS690},"
Wolke Liue6db1112007-04-27 12:20:57 +0200161 "{ATI, RS780},"
162 "{ATI, R600},"
Herton Ronaldo Krzesinski2797f722007-11-05 18:21:56 +0100163 "{ATI, RV630},"
164 "{ATI, RV610},"
Wolke Liu27da1832007-11-16 11:06:30 +0100165 "{ATI, RV670},"
166 "{ATI, RV635},"
167 "{ATI, RV620},"
168 "{ATI, RV770},"
Takashi Iwaifc20a562005-05-12 15:00:41 +0200169 "{VIA, VT8251},"
Takashi Iwai47672312005-08-12 16:44:04 +0200170 "{VIA, VT8237A},"
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200171 "{SiS, SIS966},"
172 "{ULI, M5461}}");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173MODULE_DESCRIPTION("Intel HDA driver");
174
Takashi Iwai4abc1cc2009-05-19 12:16:46 +0200175#ifdef CONFIG_SND_VERBOSE_PRINTK
176#define SFX /* nop */
177#else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178#define SFX "hda-intel: "
Takashi Iwai4abc1cc2009-05-19 12:16:46 +0200179#endif
Takashi Iwaicb53c622007-08-10 17:21:45 +0200180
Takashi Iwaia82d51e2012-04-26 12:23:42 +0200181#if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
182#ifdef CONFIG_SND_HDA_CODEC_HDMI
183#define SUPPORT_VGA_SWITCHEROO
184#endif
185#endif
186
187
Takashi Iwaicb53c622007-08-10 17:21:45 +0200188/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 * registers
190 */
191#define ICH6_REG_GCAP 0x00
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200192#define ICH6_GCAP_64OK (1 << 0) /* 64bit address support */
193#define ICH6_GCAP_NSDO (3 << 1) /* # of serial data out signals */
194#define ICH6_GCAP_BSS (31 << 3) /* # of bidirectional streams */
195#define ICH6_GCAP_ISS (15 << 8) /* # of input streams */
196#define ICH6_GCAP_OSS (15 << 12) /* # of output streams */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197#define ICH6_REG_VMIN 0x02
198#define ICH6_REG_VMAJ 0x03
199#define ICH6_REG_OUTPAY 0x04
200#define ICH6_REG_INPAY 0x06
201#define ICH6_REG_GCTL 0x08
Takashi Iwai8a933ec2009-05-31 09:28:12 +0200202#define ICH6_GCTL_RESET (1 << 0) /* controller reset */
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200203#define ICH6_GCTL_FCNTRL (1 << 1) /* flush control */
204#define ICH6_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205#define ICH6_REG_WAKEEN 0x0c
206#define ICH6_REG_STATESTS 0x0e
207#define ICH6_REG_GSTS 0x10
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200208#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209#define ICH6_REG_INTCTL 0x20
210#define ICH6_REG_INTSTS 0x24
Jaroslav Kyselae5463722010-05-11 10:21:46 +0200211#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
Takashi Iwai8b0bd222011-06-10 14:56:26 +0200212#define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */
213#define ICH6_REG_SSYNC 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214#define ICH6_REG_CORBLBASE 0x40
215#define ICH6_REG_CORBUBASE 0x44
216#define ICH6_REG_CORBWP 0x48
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200217#define ICH6_REG_CORBRP 0x4a
218#define ICH6_CORBRP_RST (1 << 15) /* read pointer reset */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219#define ICH6_REG_CORBCTL 0x4c
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200220#define ICH6_CORBCTL_RUN (1 << 1) /* enable DMA */
221#define ICH6_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222#define ICH6_REG_CORBSTS 0x4d
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200223#define ICH6_CORBSTS_CMEI (1 << 0) /* memory error indication */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224#define ICH6_REG_CORBSIZE 0x4e
225
226#define ICH6_REG_RIRBLBASE 0x50
227#define ICH6_REG_RIRBUBASE 0x54
228#define ICH6_REG_RIRBWP 0x58
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200229#define ICH6_RIRBWP_RST (1 << 15) /* write pointer reset */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230#define ICH6_REG_RINTCNT 0x5a
231#define ICH6_REG_RIRBCTL 0x5c
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200232#define ICH6_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */
233#define ICH6_RBCTL_DMA_EN (1 << 1) /* enable DMA */
234#define ICH6_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#define ICH6_REG_RIRBSTS 0x5d
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200236#define ICH6_RBSTS_IRQ (1 << 0) /* response irq */
237#define ICH6_RBSTS_OVERRUN (1 << 2) /* overrun irq */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238#define ICH6_REG_RIRBSIZE 0x5e
239
240#define ICH6_REG_IC 0x60
241#define ICH6_REG_IR 0x64
242#define ICH6_REG_IRS 0x68
243#define ICH6_IRS_VALID (1<<1)
244#define ICH6_IRS_BUSY (1<<0)
245
246#define ICH6_REG_DPLBASE 0x70
247#define ICH6_REG_DPUBASE 0x74
248#define ICH6_DPLBASE_ENABLE 0x1 /* Enable position buffer */
249
250/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
251enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
252
253/* stream register offsets from stream base */
254#define ICH6_REG_SD_CTL 0x00
255#define ICH6_REG_SD_STS 0x03
256#define ICH6_REG_SD_LPIB 0x04
257#define ICH6_REG_SD_CBL 0x08
258#define ICH6_REG_SD_LVI 0x0c
259#define ICH6_REG_SD_FIFOW 0x0e
260#define ICH6_REG_SD_FIFOSIZE 0x10
261#define ICH6_REG_SD_FORMAT 0x12
262#define ICH6_REG_SD_BDLPL 0x18
263#define ICH6_REG_SD_BDLPU 0x1c
264
265/* PCI space */
266#define ICH6_PCIREG_TCSEL 0x44
267
268/*
269 * other constants
270 */
271
272/* max number of SDs */
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200273/* ICH, ATI and VIA have 4 playback and 4 capture */
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200274#define ICH6_NUM_CAPTURE 4
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200275#define ICH6_NUM_PLAYBACK 4
276
277/* ULI has 6 playback and 5 capture */
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200278#define ULI_NUM_CAPTURE 5
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200279#define ULI_NUM_PLAYBACK 6
280
Felix Kuehling778b6e12006-05-17 11:22:21 +0200281/* ATI HDMI has 1 playback and 0 capture */
Felix Kuehling778b6e12006-05-17 11:22:21 +0200282#define ATIHDMI_NUM_CAPTURE 0
Felix Kuehling778b6e12006-05-17 11:22:21 +0200283#define ATIHDMI_NUM_PLAYBACK 1
284
Kailang Yangf2690022008-05-27 11:44:55 +0200285/* TERA has 4 playback and 3 capture */
286#define TERA_NUM_CAPTURE 3
287#define TERA_NUM_PLAYBACK 4
288
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200289/* this number is statically defined for simplicity */
290#define MAX_AZX_DEV 16
291
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292/* max number of fragments - we may use more if allocating more pages for BDL */
Takashi Iwai4ce107b2008-02-06 14:50:19 +0100293#define BDL_SIZE 4096
294#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
295#define AZX_MAX_FRAG 32
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296/* max buffer size - no h/w limit, you can increase as you like */
297#define AZX_MAX_BUF_SIZE (1024*1024*1024)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
299/* RIRB int mask: overrun[2], response[0] */
300#define RIRB_INT_RESPONSE 0x01
301#define RIRB_INT_OVERRUN 0x04
302#define RIRB_INT_MASK 0x05
303
Takashi Iwai2f5983f2008-09-03 16:00:44 +0200304/* STATESTS int mask: S3,SD2,SD1,SD0 */
Wei Ni7445dfc2010-03-03 15:05:53 +0800305#define AZX_MAX_CODECS 8
306#define AZX_DEFAULT_CODECS 4
Wu Fengguangdeadff12009-08-01 18:45:16 +0800307#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
309/* SD_CTL bits */
310#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
311#define SD_CTL_DMA_START 0x02 /* stream DMA start bit */
Takashi Iwai850f0e52008-03-18 17:11:05 +0100312#define SD_CTL_STRIPE (3 << 16) /* stripe control */
313#define SD_CTL_TRAFFIC_PRIO (1 << 18) /* traffic priority */
314#define SD_CTL_DIR (1 << 19) /* bi-directional stream */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315#define SD_CTL_STREAM_TAG_MASK (0xf << 20)
316#define SD_CTL_STREAM_TAG_SHIFT 20
317
318/* SD_CTL and SD_STS */
319#define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */
320#define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */
321#define SD_INT_COMPLETE 0x04 /* completion interrupt */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200322#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\
323 SD_INT_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
325/* SD_STS */
326#define SD_STS_FIFO_READY 0x20 /* FIFO ready */
327
328/* INTCTL and INTSTS */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200329#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */
330#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
331#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333/* below are so far hardcoded - should read registers in future */
334#define ICH6_MAX_CORB_ENTRIES 256
335#define ICH6_MAX_RIRB_ENTRIES 256
336
Takashi Iwaic74db862005-05-12 14:26:27 +0200337/* position fix mode */
338enum {
Takashi Iwai0be3b5d2005-09-05 17:11:40 +0200339 POS_FIX_AUTO,
Takashi Iwaid2e1c972008-06-10 17:53:34 +0200340 POS_FIX_LPIB,
Takashi Iwai0be3b5d2005-09-05 17:11:40 +0200341 POS_FIX_POSBUF,
David Henningsson4cb36312010-09-30 10:12:50 +0200342 POS_FIX_VIACOMBO,
Takashi Iwaia6f2fd52012-02-28 11:58:40 +0100343 POS_FIX_COMBO,
Takashi Iwaic74db862005-05-12 14:26:27 +0200344};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345
Frederick Lif5d40b32005-05-12 14:55:20 +0200346/* Defines for ATI HD Audio support in SB450 south bridge */
Frederick Lif5d40b32005-05-12 14:55:20 +0200347#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42
348#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02
349
Vinod Gda3fca22005-09-13 18:49:12 +0200350/* Defines for Nvidia HDA support */
351#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
352#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
Peer Chen320dcc32008-08-20 16:43:24 -0700353#define NVIDIA_HDA_ISTRM_COH 0x4d
354#define NVIDIA_HDA_OSTRM_COH 0x4c
355#define NVIDIA_HDA_ENABLE_COHBIT 0x01
Frederick Lif5d40b32005-05-12 14:55:20 +0200356
Takashi Iwai90a5ad52008-02-22 18:36:22 +0100357/* Defines for Intel SCH HDA snoop control */
358#define INTEL_SCH_HDA_DEVC 0x78
359#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
360
Joseph Chan0e153472008-08-26 14:38:03 +0200361/* Define IN stream 0 FIFO size offset in VIA controller */
362#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90
363/* Define VIA HD Audio Device ID*/
364#define VIA_HDAC_DEVICE_ID 0x3288
365
Yang, Libinc4da29c2008-11-13 11:07:07 +0100366/* HD Audio class code */
367#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
Takashi Iwai90a5ad52008-02-22 18:36:22 +0100368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 */
371
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100372struct azx_dev {
Takashi Iwai4ce107b2008-02-06 14:50:19 +0100373 struct snd_dma_buffer bdl; /* BDL buffer */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200374 u32 *posbuf; /* position buffer pointer */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Takashi Iwaid01ce992007-07-27 16:52:19 +0200376 unsigned int bufsize; /* size of the play buffer in bytes */
Takashi Iwai9ad593f2008-05-16 12:34:47 +0200377 unsigned int period_bytes; /* size of the period in bytes */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200378 unsigned int frags; /* number for period in the play buffer */
379 unsigned int fifo_size; /* FIFO size */
Jaroslav Kyselae5463722010-05-11 10:21:46 +0200380 unsigned long start_wallclk; /* start + minimum wallclk */
381 unsigned long period_wallclk; /* wallclk for period */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Takashi Iwaid01ce992007-07-27 16:52:19 +0200383 void __iomem *sd_addr; /* stream descriptor pointer */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Takashi Iwaid01ce992007-07-27 16:52:19 +0200385 u32 sd_int_sta_mask; /* stream int status mask */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
387 /* pcm support */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200388 struct snd_pcm_substream *substream; /* assigned substream,
389 * set in PCM open
390 */
391 unsigned int format_val; /* format value to be set in the
392 * controller and the codec
393 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 unsigned char stream_tag; /* assigned stream */
395 unsigned char index; /* stream index */
Takashi Iwaid5cf9912011-10-06 10:07:58 +0200396 int assigned_key; /* last device# key assigned to */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Pavel Machek927fc862006-08-31 17:03:43 +0200398 unsigned int opened :1;
399 unsigned int running :1;
Takashi Iwai675f25d2008-06-10 17:53:20 +0200400 unsigned int irq_pending :1;
Joseph Chan0e153472008-08-26 14:38:03 +0200401 /*
402 * For VIA:
403 * A flag to ensure DMA position is 0
404 * when link position is not greater than FIFO size
405 */
406 unsigned int insufficient :1;
Takashi Iwai27fe48d92011-09-28 17:16:09 +0200407 unsigned int wc_marked:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408};
409
410/* CORB/RIRB */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100411struct azx_rb {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 u32 *buf; /* CORB/RIRB buffer
413 * Each CORB entry is 4byte, RIRB is 8byte
414 */
415 dma_addr_t addr; /* physical address of CORB/RIRB buffer */
416 /* for RIRB */
417 unsigned short rp, wp; /* read/write pointers */
Wu Fengguangdeadff12009-08-01 18:45:16 +0800418 int cmds[AZX_MAX_CODECS]; /* number of pending requests */
419 u32 res[AZX_MAX_CODECS]; /* last read value */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420};
421
Takashi Iwai01b65bf2011-11-24 14:31:46 +0100422struct azx_pcm {
423 struct azx *chip;
424 struct snd_pcm *pcm;
425 struct hda_codec *codec;
426 struct hda_pcm_stream *hinfo[2];
427 struct list_head list;
428};
429
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100430struct azx {
431 struct snd_card *card;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 struct pci_dev *pci;
Takashi Iwai555e2192008-06-10 17:53:34 +0200433 int dev_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200435 /* chip type specific */
436 int driver_type;
Takashi Iwai9477c582011-05-25 09:11:37 +0200437 unsigned int driver_caps;
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200438 int playback_streams;
439 int playback_index_offset;
440 int capture_streams;
441 int capture_index_offset;
442 int num_streams;
443
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 /* pci resources */
445 unsigned long addr;
446 void __iomem *remap_addr;
447 int irq;
448
449 /* locks */
450 spinlock_t reg_lock;
Ingo Molnar62932df2006-01-16 16:34:20 +0100451 struct mutex open_mutex;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200453 /* streams (x num_streams) */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100454 struct azx_dev *azx_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
456 /* PCM */
Takashi Iwai01b65bf2011-11-24 14:31:46 +0100457 struct list_head pcm_list; /* azx_pcm list */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 /* HD codec */
460 unsigned short codec_mask;
Takashi Iwaif1eaaee2009-02-13 08:16:55 +0100461 int codec_probe_mask; /* copied from probe_mask option */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 struct hda_bus *bus;
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +0100463 unsigned int beep_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464
465 /* CORB/RIRB */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100466 struct azx_rb corb;
467 struct azx_rb rirb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468
Takashi Iwai4ce107b2008-02-06 14:50:19 +0100469 /* CORB/RIRB and position buffers */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 struct snd_dma_buffer rb;
471 struct snd_dma_buffer posbuf;
Takashi Iwaic74db862005-05-12 14:26:27 +0200472
473 /* flags */
Shahin Ghazinouribeaffc32010-05-11 08:19:55 +0200474 int position_fix[2]; /* for both playback/capture streams */
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200475 int poll_count;
Takashi Iwaicb53c622007-08-10 17:21:45 +0200476 unsigned int running :1;
Pavel Machek927fc862006-08-31 17:03:43 +0200477 unsigned int initialized :1;
478 unsigned int single_cmd :1;
479 unsigned int polling_mode :1;
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200480 unsigned int msi :1;
Takashi Iwaia6a950a2008-06-10 17:53:35 +0200481 unsigned int irq_pending_warned :1;
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +0100482 unsigned int probing :1; /* codec probing phase */
Takashi Iwai27fe48d92011-09-28 17:16:09 +0200483 unsigned int snoop:1;
Takashi Iwai52409aa2012-01-23 17:10:24 +0100484 unsigned int align_buffer_size:1;
Takashi Iwaia82d51e2012-04-26 12:23:42 +0200485 unsigned int region_requested:1;
486
487 /* VGA-switcheroo setup */
488 unsigned int use_vga_switcheroo:1;
489 unsigned int init_failed:1; /* delayed init failed */
490 unsigned int disabled:1; /* disabled by VGA-switcher */
Takashi Iwai43bbb6c2007-07-06 20:22:05 +0200491
492 /* for debugging */
Wu Fengguangfeb27342009-08-01 19:17:14 +0800493 unsigned int last_cmd[AZX_MAX_CODECS];
Takashi Iwai9ad593f2008-05-16 12:34:47 +0200494
495 /* for pending irqs */
496 struct work_struct irq_pending_work;
Takashi Iwai0cbf0092008-10-29 16:18:25 +0100497
498 /* reboot notifier (for mysterious hangup problem at power-down) */
499 struct notifier_block reboot_notifier;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500};
501
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200502/* driver types */
503enum {
504 AZX_DRIVER_ICH,
Seth Heasley32679f92010-02-22 17:31:09 -0800505 AZX_DRIVER_PCH,
Tobin Davis4979bca2008-01-30 08:13:55 +0100506 AZX_DRIVER_SCH,
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200507 AZX_DRIVER_ATI,
Felix Kuehling778b6e12006-05-17 11:22:21 +0200508 AZX_DRIVER_ATIHDMI,
Andiry Xu1815b342011-12-14 16:10:27 +0800509 AZX_DRIVER_ATIHDMI_NS,
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200510 AZX_DRIVER_VIA,
511 AZX_DRIVER_SIS,
512 AZX_DRIVER_ULI,
Vinod Gda3fca22005-09-13 18:49:12 +0200513 AZX_DRIVER_NVIDIA,
Kailang Yangf2690022008-05-27 11:44:55 +0200514 AZX_DRIVER_TERA,
Takashi Iwai14d34f12010-10-21 09:03:25 +0200515 AZX_DRIVER_CTX,
Takashi Iwai5ae763b2012-05-08 10:34:08 +0200516 AZX_DRIVER_CTHDA,
Yang, Libinc4da29c2008-11-13 11:07:07 +0100517 AZX_DRIVER_GENERIC,
Takashi Iwai2f5983f2008-09-03 16:00:44 +0200518 AZX_NUM_DRIVERS, /* keep this as last entry */
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200519};
520
Takashi Iwai9477c582011-05-25 09:11:37 +0200521/* driver quirks (capabilities) */
522/* bits 0-7 are used for indicating driver type */
523#define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */
524#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
525#define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */
526#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */
527#define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */
528#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */
529#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */
530#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
531#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
532#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
533#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
534#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
Takashi Iwai8b0bd222011-06-10 14:56:26 +0200535#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -0500536#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
Takashi Iwai7bfe0592012-01-23 17:53:39 +0100537#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
Takashi Iwai5ae763b2012-05-08 10:34:08 +0200538#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
Seth Heasleyc20c5a82012-06-14 14:23:53 -0700539#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
Takashi Iwai9477c582011-05-25 09:11:37 +0200540
541/* quirks for ATI SB / AMD Hudson */
542#define AZX_DCAPS_PRESET_ATI_SB \
543 (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \
544 AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
545
546/* quirks for ATI/AMD HDMI */
547#define AZX_DCAPS_PRESET_ATI_HDMI \
548 (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB)
549
550/* quirks for Nvidia */
551#define AZX_DCAPS_PRESET_NVIDIA \
Takashi Iwai7bfe0592012-01-23 17:53:39 +0100552 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
553 AZX_DCAPS_ALIGN_BUFSIZE)
Takashi Iwai9477c582011-05-25 09:11:37 +0200554
Takashi Iwai5ae763b2012-05-08 10:34:08 +0200555#define AZX_DCAPS_PRESET_CTHDA \
556 (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY)
557
Takashi Iwaia82d51e2012-04-26 12:23:42 +0200558/*
559 * VGA-switcher support
560 */
561#ifdef SUPPORT_VGA_SWITCHEROO
562#define DELAYED_INIT_MARK
563#define DELAYED_INITDATA_MARK
564#define use_vga_switcheroo(chip) ((chip)->use_vga_switcheroo)
565#else
566#define DELAYED_INIT_MARK __devinit
567#define DELAYED_INITDATA_MARK __devinitdata
568#define use_vga_switcheroo(chip) 0
569#endif
570
571static char *driver_short_names[] DELAYED_INITDATA_MARK = {
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200572 [AZX_DRIVER_ICH] = "HDA Intel",
Seth Heasley32679f92010-02-22 17:31:09 -0800573 [AZX_DRIVER_PCH] = "HDA Intel PCH",
Tobin Davis4979bca2008-01-30 08:13:55 +0100574 [AZX_DRIVER_SCH] = "HDA Intel MID",
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200575 [AZX_DRIVER_ATI] = "HDA ATI SB",
Felix Kuehling778b6e12006-05-17 11:22:21 +0200576 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
Andiry Xu1815b342011-12-14 16:10:27 +0800577 [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200578 [AZX_DRIVER_VIA] = "HDA VIA VT82xx",
579 [AZX_DRIVER_SIS] = "HDA SIS966",
Vinod Gda3fca22005-09-13 18:49:12 +0200580 [AZX_DRIVER_ULI] = "HDA ULI M5461",
581 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
Kailang Yangf2690022008-05-27 11:44:55 +0200582 [AZX_DRIVER_TERA] = "HDA Teradici",
Takashi Iwai14d34f12010-10-21 09:03:25 +0200583 [AZX_DRIVER_CTX] = "HDA Creative",
Takashi Iwai5ae763b2012-05-08 10:34:08 +0200584 [AZX_DRIVER_CTHDA] = "HDA Creative",
Yang, Libinc4da29c2008-11-13 11:07:07 +0100585 [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200586};
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588/*
589 * macros for easy use
590 */
591#define azx_writel(chip,reg,value) \
592 writel(value, (chip)->remap_addr + ICH6_REG_##reg)
593#define azx_readl(chip,reg) \
594 readl((chip)->remap_addr + ICH6_REG_##reg)
595#define azx_writew(chip,reg,value) \
596 writew(value, (chip)->remap_addr + ICH6_REG_##reg)
597#define azx_readw(chip,reg) \
598 readw((chip)->remap_addr + ICH6_REG_##reg)
599#define azx_writeb(chip,reg,value) \
600 writeb(value, (chip)->remap_addr + ICH6_REG_##reg)
601#define azx_readb(chip,reg) \
602 readb((chip)->remap_addr + ICH6_REG_##reg)
603
604#define azx_sd_writel(dev,reg,value) \
605 writel(value, (dev)->sd_addr + ICH6_REG_##reg)
606#define azx_sd_readl(dev,reg) \
607 readl((dev)->sd_addr + ICH6_REG_##reg)
608#define azx_sd_writew(dev,reg,value) \
609 writew(value, (dev)->sd_addr + ICH6_REG_##reg)
610#define azx_sd_readw(dev,reg) \
611 readw((dev)->sd_addr + ICH6_REG_##reg)
612#define azx_sd_writeb(dev,reg,value) \
613 writeb(value, (dev)->sd_addr + ICH6_REG_##reg)
614#define azx_sd_readb(dev,reg) \
615 readb((dev)->sd_addr + ICH6_REG_##reg)
616
617/* for pcm support */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100618#define get_azx_dev(substream) (substream->runtime->private_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Takashi Iwai27fe48d92011-09-28 17:16:09 +0200620#ifdef CONFIG_X86
621static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on)
622{
623 if (azx_snoop(chip))
624 return;
625 if (addr && size) {
626 int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
627 if (on)
628 set_memory_wc((unsigned long)addr, pages);
629 else
630 set_memory_wb((unsigned long)addr, pages);
631 }
632}
633
634static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
635 bool on)
636{
637 __mark_pages_wc(chip, buf->area, buf->bytes, on);
638}
639static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
640 struct snd_pcm_runtime *runtime, bool on)
641{
642 if (azx_dev->wc_marked != on) {
643 __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on);
644 azx_dev->wc_marked = on;
645 }
646}
647#else
648/* NOP for other archs */
649static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
650 bool on)
651{
652}
653static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
654 struct snd_pcm_runtime *runtime, bool on)
655{
656}
657#endif
658
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200659static int azx_acquire_irq(struct azx *chip, int do_disconnect);
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200660static int azx_send_cmd(struct hda_bus *bus, unsigned int val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661/*
662 * Interface for HD codec
663 */
664
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665/*
666 * CORB / RIRB interface
667 */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100668static int azx_alloc_cmd_io(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669{
670 int err;
671
672 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200673 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
674 snd_dma_pci_data(chip->pci),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 PAGE_SIZE, &chip->rb);
676 if (err < 0) {
677 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
678 return err;
679 }
Takashi Iwai27fe48d92011-09-28 17:16:09 +0200680 mark_pages_wc(chip, &chip->rb, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 return 0;
682}
683
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100684static void azx_init_cmd_io(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
Wu Fengguangcdb1fbf2009-08-01 18:47:41 +0800686 spin_lock_irq(&chip->reg_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 /* CORB set up */
688 chip->corb.addr = chip->rb.addr;
689 chip->corb.buf = (u32 *)chip->rb.area;
690 azx_writel(chip, CORBLBASE, (u32)chip->corb.addr);
Takashi Iwai766979e2008-06-13 20:53:56 +0200691 azx_writel(chip, CORBUBASE, upper_32_bits(chip->corb.addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200693 /* set the corb size to 256 entries (ULI requires explicitly) */
694 azx_writeb(chip, CORBSIZE, 0x02);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 /* set the corb write pointer to 0 */
696 azx_writew(chip, CORBWP, 0);
697 /* reset the corb hw read pointer */
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200698 azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 /* enable corb dma */
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200700 azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
702 /* RIRB set up */
703 chip->rirb.addr = chip->rb.addr + 2048;
704 chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
Wu Fengguangdeadff12009-08-01 18:45:16 +0800705 chip->rirb.wp = chip->rirb.rp = 0;
706 memset(chip->rirb.cmds, 0, sizeof(chip->rirb.cmds));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr);
Takashi Iwai766979e2008-06-13 20:53:56 +0200708 azx_writel(chip, RIRBUBASE, upper_32_bits(chip->rirb.addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
Takashi Iwai07e4ca52005-08-24 14:14:57 +0200710 /* set the rirb size to 256 entries (ULI requires explicitly) */
711 azx_writeb(chip, RIRBSIZE, 0x02);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 /* reset the rirb hw write pointer */
Takashi Iwaib21fadb2009-05-28 12:26:15 +0200713 azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 /* set N=1, get RIRB response interrupt for new entry */
Takashi Iwai9477c582011-05-25 09:11:37 +0200715 if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
Takashi Iwai14d34f12010-10-21 09:03:25 +0200716 azx_writew(chip, RINTCNT, 0xc0);
717 else
718 azx_writew(chip, RINTCNT, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 /* enable rirb dma and response irq */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
Wu Fengguangcdb1fbf2009-08-01 18:47:41 +0800721 spin_unlock_irq(&chip->reg_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722}
723
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100724static void azx_free_cmd_io(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725{
Wu Fengguangcdb1fbf2009-08-01 18:47:41 +0800726 spin_lock_irq(&chip->reg_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 /* disable ringbuffer DMAs */
728 azx_writeb(chip, RIRBCTL, 0);
729 azx_writeb(chip, CORBCTL, 0);
Wu Fengguangcdb1fbf2009-08-01 18:47:41 +0800730 spin_unlock_irq(&chip->reg_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}
732
Wu Fengguangdeadff12009-08-01 18:45:16 +0800733static unsigned int azx_command_addr(u32 cmd)
734{
735 unsigned int addr = cmd >> 28;
736
737 if (addr >= AZX_MAX_CODECS) {
738 snd_BUG();
739 addr = 0;
740 }
741
742 return addr;
743}
744
745static unsigned int azx_response_addr(u32 res)
746{
747 unsigned int addr = res & 0xf;
748
749 if (addr >= AZX_MAX_CODECS) {
750 snd_BUG();
751 addr = 0;
752 }
753
754 return addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755}
756
757/* send a command */
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100758static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759{
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100760 struct azx *chip = bus->private_data;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800761 unsigned int addr = azx_command_addr(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 unsigned int wp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
Wu Fengguangc32649f2009-08-01 18:48:12 +0800764 spin_lock_irq(&chip->reg_lock);
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 /* add command to corb */
767 wp = azx_readb(chip, CORBWP);
768 wp++;
769 wp %= ICH6_MAX_CORB_ENTRIES;
770
Wu Fengguangdeadff12009-08-01 18:45:16 +0800771 chip->rirb.cmds[addr]++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 chip->corb.buf[wp] = cpu_to_le32(val);
773 azx_writel(chip, CORBWP, wp);
Wu Fengguangc32649f2009-08-01 18:48:12 +0800774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 spin_unlock_irq(&chip->reg_lock);
776
777 return 0;
778}
779
780#define ICH6_RIRB_EX_UNSOL_EV (1<<4)
781
782/* retrieve RIRB entry - called from interrupt handler */
Takashi Iwaia98f90f2005-11-17 14:59:02 +0100783static void azx_update_rirb(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784{
785 unsigned int rp, wp;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800786 unsigned int addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 u32 res, res_ex;
788
789 wp = azx_readb(chip, RIRBWP);
790 if (wp == chip->rirb.wp)
791 return;
792 chip->rirb.wp = wp;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800793
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 while (chip->rirb.rp != wp) {
795 chip->rirb.rp++;
796 chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
797
798 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
799 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
800 res = le32_to_cpu(chip->rirb.buf[rp]);
Wu Fengguangdeadff12009-08-01 18:45:16 +0800801 addr = azx_response_addr(res_ex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
803 snd_hda_queue_unsol_event(chip->bus, res, res_ex);
Wu Fengguangdeadff12009-08-01 18:45:16 +0800804 else if (chip->rirb.cmds[addr]) {
805 chip->rirb.res[addr] = res;
Takashi Iwai2add9b92008-03-18 09:47:06 +0100806 smp_wmb();
Wu Fengguangdeadff12009-08-01 18:45:16 +0800807 chip->rirb.cmds[addr]--;
Wu Fengguange310bb02009-08-01 19:18:45 +0800808 } else
809 snd_printk(KERN_ERR SFX "spurious response %#x:%#x, "
810 "last cmd=%#08x\n",
811 res, res_ex,
812 chip->last_cmd[addr]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 }
814}
815
816/* receive a response */
Wu Fengguangdeadff12009-08-01 18:45:16 +0800817static unsigned int azx_rirb_get_response(struct hda_bus *bus,
818 unsigned int addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819{
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100820 struct azx *chip = bus->private_data;
Takashi Iwai5c79b1f2006-09-21 13:34:13 +0200821 unsigned long timeout;
David Henningsson32cf4022012-05-04 11:05:55 +0200822 unsigned long loopcounter;
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200823 int do_poll = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
Takashi Iwai5c79b1f2006-09-21 13:34:13 +0200825 again:
826 timeout = jiffies + msecs_to_jiffies(1000);
David Henningsson32cf4022012-05-04 11:05:55 +0200827
828 for (loopcounter = 0;; loopcounter++) {
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200829 if (chip->polling_mode || do_poll) {
Takashi Iwaie96224a2006-08-21 17:57:44 +0200830 spin_lock_irq(&chip->reg_lock);
831 azx_update_rirb(chip);
832 spin_unlock_irq(&chip->reg_lock);
833 }
Wu Fengguangdeadff12009-08-01 18:45:16 +0800834 if (!chip->rirb.cmds[addr]) {
Takashi Iwai2add9b92008-03-18 09:47:06 +0100835 smp_rmb();
Takashi Iwaib6132912009-03-24 07:36:09 +0100836 bus->rirb_error = 0;
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200837
838 if (!do_poll)
839 chip->poll_count = 0;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800840 return chip->rirb.res[addr]; /* the last value */
Takashi Iwai2add9b92008-03-18 09:47:06 +0100841 }
Takashi Iwai28a0d9d2008-01-18 15:32:32 +0100842 if (time_after(jiffies, timeout))
843 break;
David Henningsson32cf4022012-05-04 11:05:55 +0200844 if (bus->needs_damn_long_delay || loopcounter > 3000)
Takashi Iwai52987652008-01-16 16:09:47 +0100845 msleep(2); /* temporary workaround */
846 else {
847 udelay(10);
848 cond_resched();
849 }
Takashi Iwai28a0d9d2008-01-18 15:32:32 +0100850 }
Takashi Iwai5c79b1f2006-09-21 13:34:13 +0200851
Maxim Levitsky1eb6dc72010-02-04 22:21:47 +0200852 if (!chip->polling_mode && chip->poll_count < 2) {
853 snd_printdd(SFX "azx_get_response timeout, "
854 "polling the codec once: last cmd=0x%08x\n",
855 chip->last_cmd[addr]);
856 do_poll = 1;
857 chip->poll_count++;
858 goto again;
859 }
860
861
Takashi Iwai23c4a882009-10-30 13:21:49 +0100862 if (!chip->polling_mode) {
863 snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
864 "switching to polling mode: last cmd=0x%08x\n",
865 chip->last_cmd[addr]);
866 chip->polling_mode = 1;
867 goto again;
868 }
869
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200870 if (chip->msi) {
Takashi Iwai4abc1cc2009-05-19 12:16:46 +0200871 snd_printk(KERN_WARNING SFX "No response from codec, "
Wu Fengguangfeb27342009-08-01 19:17:14 +0800872 "disabling MSI: last cmd=0x%08x\n",
873 chip->last_cmd[addr]);
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200874 free_irq(chip->irq, chip);
875 chip->irq = -1;
876 pci_disable_msi(chip->pci);
877 chip->msi = 0;
Takashi Iwaib6132912009-03-24 07:36:09 +0100878 if (azx_acquire_irq(chip, 1) < 0) {
879 bus->rirb_error = 1;
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200880 return -1;
Takashi Iwaib6132912009-03-24 07:36:09 +0100881 }
Takashi Iwai68e7fff2006-10-23 13:40:59 +0200882 goto again;
883 }
884
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +0100885 if (chip->probing) {
886 /* If this critical timeout happens during the codec probing
887 * phase, this is likely an access to a non-existing codec
888 * slot. Better to return an error and reset the system.
889 */
890 return -1;
891 }
892
Takashi Iwai8dd78332009-06-02 01:16:07 +0200893 /* a fatal communication error; need either to reset or to fallback
894 * to the single_cmd mode
895 */
Takashi Iwaib6132912009-03-24 07:36:09 +0100896 bus->rirb_error = 1;
Takashi Iwaib20f3b82009-06-02 01:20:22 +0200897 if (bus->allow_bus_reset && !bus->response_reset && !bus->in_reset) {
Takashi Iwai8dd78332009-06-02 01:16:07 +0200898 bus->response_reset = 1;
899 return -1; /* give a chance to retry */
900 }
901
902 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
903 "switching to single_cmd mode: last cmd=0x%08x\n",
Wu Fengguangfeb27342009-08-01 19:17:14 +0800904 chip->last_cmd[addr]);
Takashi Iwai8dd78332009-06-02 01:16:07 +0200905 chip->single_cmd = 1;
906 bus->response_reset = 0;
Takashi Iwai1a696972009-11-07 09:49:04 +0100907 /* release CORB/RIRB */
Takashi Iwai4fcd3922009-05-25 18:34:52 +0200908 azx_free_cmd_io(chip);
Takashi Iwai1a696972009-11-07 09:49:04 +0100909 /* disable unsolicited responses */
910 azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
Takashi Iwai5c79b1f2006-09-21 13:34:13 +0200911 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912}
913
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914/*
915 * Use the single immediate command instead of CORB/RIRB for simplicity
916 *
917 * Note: according to Intel, this is not preferred use. The command was
918 * intended for the BIOS only, and may get confused with unsolicited
919 * responses. So, we shouldn't use it for normal operation from the
920 * driver.
921 * I left the codes, however, for debugging/testing purposes.
922 */
923
Takashi Iwaib05a7d42009-05-28 11:59:12 +0200924/* receive a response */
Wu Fengguangdeadff12009-08-01 18:45:16 +0800925static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
Takashi Iwaib05a7d42009-05-28 11:59:12 +0200926{
927 int timeout = 50;
928
929 while (timeout--) {
930 /* check IRV busy bit */
931 if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
932 /* reuse rirb.res as the response return value */
Wu Fengguangdeadff12009-08-01 18:45:16 +0800933 chip->rirb.res[addr] = azx_readl(chip, IR);
Takashi Iwaib05a7d42009-05-28 11:59:12 +0200934 return 0;
935 }
936 udelay(1);
937 }
938 if (printk_ratelimit())
939 snd_printd(SFX "get_response timeout: IRS=0x%x\n",
940 azx_readw(chip, IRS));
Wu Fengguangdeadff12009-08-01 18:45:16 +0800941 chip->rirb.res[addr] = -1;
Takashi Iwaib05a7d42009-05-28 11:59:12 +0200942 return -EIO;
943}
944
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945/* send a command */
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100946static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947{
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100948 struct azx *chip = bus->private_data;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800949 unsigned int addr = azx_command_addr(val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 int timeout = 50;
951
Takashi Iwai8dd78332009-06-02 01:16:07 +0200952 bus->rirb_error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 while (timeout--) {
954 /* check ICB busy bit */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200955 if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 /* Clear IRV valid bit */
Takashi Iwaid01ce992007-07-27 16:52:19 +0200957 azx_writew(chip, IRS, azx_readw(chip, IRS) |
958 ICH6_IRS_VALID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 azx_writel(chip, IC, val);
Takashi Iwaid01ce992007-07-27 16:52:19 +0200960 azx_writew(chip, IRS, azx_readw(chip, IRS) |
961 ICH6_IRS_BUSY);
Wu Fengguangdeadff12009-08-01 18:45:16 +0800962 return azx_single_wait_for_response(chip, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 }
964 udelay(1);
965 }
Marc Boucher1cfd52b2008-01-22 15:29:26 +0100966 if (printk_ratelimit())
967 snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
968 azx_readw(chip, IRS), val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 return -EIO;
970}
971
972/* receive a response */
Wu Fengguangdeadff12009-08-01 18:45:16 +0800973static unsigned int azx_single_get_response(struct hda_bus *bus,
974 unsigned int addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975{
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100976 struct azx *chip = bus->private_data;
Wu Fengguangdeadff12009-08-01 18:45:16 +0800977 return chip->rirb.res[addr];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978}
979
Takashi Iwai111d3af2006-02-16 18:17:58 +0100980/*
981 * The below are the main callbacks from hda_codec.
982 *
983 * They are just the skeleton to call sub-callbacks according to the
984 * current setting of chip->single_cmd.
985 */
986
987/* send a command */
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100988static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
Takashi Iwai111d3af2006-02-16 18:17:58 +0100989{
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100990 struct azx *chip = bus->private_data;
Takashi Iwai43bbb6c2007-07-06 20:22:05 +0200991
Takashi Iwaia82d51e2012-04-26 12:23:42 +0200992 if (chip->disabled)
993 return 0;
Wu Fengguangfeb27342009-08-01 19:17:14 +0800994 chip->last_cmd[azx_command_addr(val)] = val;
Takashi Iwai111d3af2006-02-16 18:17:58 +0100995 if (chip->single_cmd)
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100996 return azx_single_send_cmd(bus, val);
Takashi Iwai111d3af2006-02-16 18:17:58 +0100997 else
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100998 return azx_corb_send_cmd(bus, val);
Takashi Iwai111d3af2006-02-16 18:17:58 +0100999}
1000
1001/* get a response */
Wu Fengguangdeadff12009-08-01 18:45:16 +08001002static unsigned int azx_get_response(struct hda_bus *bus,
1003 unsigned int addr)
Takashi Iwai111d3af2006-02-16 18:17:58 +01001004{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01001005 struct azx *chip = bus->private_data;
Takashi Iwaia82d51e2012-04-26 12:23:42 +02001006 if (chip->disabled)
1007 return 0;
Takashi Iwai111d3af2006-02-16 18:17:58 +01001008 if (chip->single_cmd)
Wu Fengguangdeadff12009-08-01 18:45:16 +08001009 return azx_single_get_response(bus, addr);
Takashi Iwai111d3af2006-02-16 18:17:58 +01001010 else
Wu Fengguangdeadff12009-08-01 18:45:16 +08001011 return azx_rirb_get_response(bus, addr);
Takashi Iwai111d3af2006-02-16 18:17:58 +01001012}
1013
Takashi Iwaicb53c622007-08-10 17:21:45 +02001014#ifdef CONFIG_SND_HDA_POWER_SAVE
Takashi Iwai33fa35e2008-11-06 16:50:40 +01001015static void azx_power_notify(struct hda_bus *bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001016#endif
Takashi Iwai111d3af2006-02-16 18:17:58 +01001017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018/* reset codec link */
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001019static int azx_reset(struct azx *chip, int full_reset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020{
1021 int count;
1022
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001023 if (!full_reset)
1024 goto __skip;
1025
Danny Tholene8a7f132007-09-11 21:41:56 +02001026 /* clear STATESTS */
1027 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
1028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 /* reset controller */
1030 azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
1031
1032 count = 50;
1033 while (azx_readb(chip, GCTL) && --count)
1034 msleep(1);
1035
1036 /* delay for >= 100us for codec PLL to settle per spec
1037 * Rev 0.9 section 5.5.1
1038 */
1039 msleep(1);
1040
1041 /* Bring controller out of reset */
1042 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
1043
1044 count = 50;
Pavel Machek927fc862006-08-31 17:03:43 +02001045 while (!azx_readb(chip, GCTL) && --count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 msleep(1);
1047
Pavel Machek927fc862006-08-31 17:03:43 +02001048 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 msleep(1);
1050
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001051 __skip:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 /* check to see if controller is ready */
Pavel Machek927fc862006-08-31 17:03:43 +02001053 if (!azx_readb(chip, GCTL)) {
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001054 snd_printd(SFX "azx_reset: controller not ready!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 return -EBUSY;
1056 }
1057
Matt41e2fce2005-07-04 17:49:55 +02001058 /* Accept unsolicited responses */
Takashi Iwai1a696972009-11-07 09:49:04 +01001059 if (!chip->single_cmd)
1060 azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
1061 ICH6_GCTL_UNSOL);
Matt41e2fce2005-07-04 17:49:55 +02001062
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 /* detect codecs */
Pavel Machek927fc862006-08-31 17:03:43 +02001064 if (!chip->codec_mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 chip->codec_mask = azx_readw(chip, STATESTS);
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001066 snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 }
1068
1069 return 0;
1070}
1071
1072
1073/*
1074 * Lowlevel interface
1075 */
1076
1077/* enable interrupts */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001078static void azx_int_enable(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079{
1080 /* enable controller CIE and GIE */
1081 azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
1082 ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN);
1083}
1084
1085/* disable interrupts */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001086static void azx_int_disable(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087{
1088 int i;
1089
1090 /* disable interrupts in stream descriptor */
Takashi Iwai07e4ca52005-08-24 14:14:57 +02001091 for (i = 0; i < chip->num_streams; i++) {
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001092 struct azx_dev *azx_dev = &chip->azx_dev[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 azx_sd_writeb(azx_dev, SD_CTL,
1094 azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK);
1095 }
1096
1097 /* disable SIE for all streams */
1098 azx_writeb(chip, INTCTL, 0);
1099
1100 /* disable controller CIE and GIE */
1101 azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
1102 ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN));
1103}
1104
1105/* clear interrupts */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001106static void azx_int_clear(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107{
1108 int i;
1109
1110 /* clear stream status */
Takashi Iwai07e4ca52005-08-24 14:14:57 +02001111 for (i = 0; i < chip->num_streams; i++) {
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001112 struct azx_dev *azx_dev = &chip->azx_dev[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
1114 }
1115
1116 /* clear STATESTS */
1117 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
1118
1119 /* clear rirb status */
1120 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1121
1122 /* clear int status */
1123 azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM);
1124}
1125
1126/* start a stream */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001127static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128{
Joseph Chan0e153472008-08-26 14:38:03 +02001129 /*
1130 * Before stream start, initialize parameter
1131 */
1132 azx_dev->insufficient = 1;
1133
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 /* enable SIE */
Wei Niccc5df02010-01-26 15:59:33 +08001135 azx_writel(chip, INTCTL,
1136 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 /* set DMA start and interrupt mask */
1138 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
1139 SD_CTL_DMA_START | SD_INT_MASK);
1140}
1141
Takashi Iwai1dddab42009-03-18 15:15:37 +01001142/* stop DMA */
1143static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
1146 ~(SD_CTL_DMA_START | SD_INT_MASK));
1147 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
Takashi Iwai1dddab42009-03-18 15:15:37 +01001148}
1149
1150/* stop a stream */
1151static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
1152{
1153 azx_stream_clear(chip, azx_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 /* disable SIE */
Wei Niccc5df02010-01-26 15:59:33 +08001155 azx_writel(chip, INTCTL,
1156 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157}
1158
1159
1160/*
Takashi Iwaicb53c622007-08-10 17:21:45 +02001161 * reset and start the controller registers
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 */
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001163static void azx_init_chip(struct azx *chip, int full_reset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164{
Takashi Iwaicb53c622007-08-10 17:21:45 +02001165 if (chip->initialized)
1166 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
1168 /* reset controller */
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001169 azx_reset(chip, full_reset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
1171 /* initialize interrupts */
1172 azx_int_clear(chip);
1173 azx_int_enable(chip);
1174
1175 /* initialize the codec command I/O */
Takashi Iwai1a696972009-11-07 09:49:04 +01001176 if (!chip->single_cmd)
1177 azx_init_cmd_io(chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Takashi Iwai0be3b5d2005-09-05 17:11:40 +02001179 /* program the position buffer */
1180 azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
Takashi Iwai766979e2008-06-13 20:53:56 +02001181 azx_writel(chip, DPUBASE, upper_32_bits(chip->posbuf.addr));
Frederick Lif5d40b32005-05-12 14:55:20 +02001182
Takashi Iwaicb53c622007-08-10 17:21:45 +02001183 chip->initialized = 1;
1184}
1185
1186/*
1187 * initialize the PCI registers
1188 */
1189/* update bits in a PCI register byte */
1190static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
1191 unsigned char mask, unsigned char val)
1192{
1193 unsigned char data;
1194
1195 pci_read_config_byte(pci, reg, &data);
1196 data &= ~mask;
1197 data |= (val & mask);
1198 pci_write_config_byte(pci, reg, data);
1199}
1200
1201static void azx_init_pci(struct azx *chip)
1202{
1203 /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
1204 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
1205 * Ensuring these bits are 0 clears playback static on some HD Audio
Adam Lackorzynskia09e89f2011-03-10 17:41:56 +01001206 * codecs.
1207 * The PCI register TCSEL is defined in the Intel manuals.
Takashi Iwaicb53c622007-08-10 17:21:45 +02001208 */
Linus Torvalds46f2cc82011-05-27 19:45:28 -07001209 if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
Takashi Iwai9477c582011-05-25 09:11:37 +02001210 snd_printdd(SFX "Clearing TCSEL\n");
Adam Lackorzynskia09e89f2011-03-10 17:41:56 +01001211 update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
Takashi Iwai9477c582011-05-25 09:11:37 +02001212 }
Takashi Iwaicb53c622007-08-10 17:21:45 +02001213
Takashi Iwai9477c582011-05-25 09:11:37 +02001214 /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
1215 * we need to enable snoop.
1216 */
1217 if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001218 snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip));
Takashi Iwaicb53c622007-08-10 17:21:45 +02001219 update_pci_byte(chip->pci,
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001220 ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
1221 azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
Takashi Iwai9477c582011-05-25 09:11:37 +02001222 }
1223
1224 /* For NVIDIA HDA, enable snoop */
1225 if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001226 snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip));
Takashi Iwaicb53c622007-08-10 17:21:45 +02001227 update_pci_byte(chip->pci,
1228 NVIDIA_HDA_TRANSREG_ADDR,
1229 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
Peer Chen320dcc32008-08-20 16:43:24 -07001230 update_pci_byte(chip->pci,
1231 NVIDIA_HDA_ISTRM_COH,
1232 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1233 update_pci_byte(chip->pci,
1234 NVIDIA_HDA_OSTRM_COH,
1235 0x01, NVIDIA_HDA_ENABLE_COHBIT);
Takashi Iwai9477c582011-05-25 09:11:37 +02001236 }
1237
1238 /* Enable SCH/PCH snoop if needed */
1239 if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) {
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001240 unsigned short snoop;
Takashi Iwai90a5ad52008-02-22 18:36:22 +01001241 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001242 if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) ||
1243 (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) {
1244 snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP;
1245 if (!azx_snoop(chip))
1246 snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP;
1247 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop);
Takashi Iwai90a5ad52008-02-22 18:36:22 +01001248 pci_read_config_word(chip->pci,
1249 INTEL_SCH_HDA_DEVC, &snoop);
Takashi Iwai90a5ad52008-02-22 18:36:22 +01001250 }
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001251 snd_printdd(SFX "SCH snoop: %s\n",
1252 (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
1253 ? "Disabled" : "Enabled");
Vinod Gda3fca22005-09-13 18:49:12 +02001254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255}
1256
1257
Takashi Iwai9ad593f2008-05-16 12:34:47 +02001258static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
1259
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260/*
1261 * interrupt handler
1262 */
David Howells7d12e782006-10-05 14:55:46 +01001263static irqreturn_t azx_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264{
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001265 struct azx *chip = dev_id;
1266 struct azx_dev *azx_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 u32 status;
Clemens Ladisch9ef04062010-05-25 09:03:40 +02001268 u8 sd_status;
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001269 int i, ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270
1271 spin_lock(&chip->reg_lock);
1272
Dan Carpenter60911062012-05-18 10:36:11 +03001273 if (chip->disabled) {
1274 spin_unlock(&chip->reg_lock);
Takashi Iwaia82d51e2012-04-26 12:23:42 +02001275 return IRQ_NONE;
Dan Carpenter60911062012-05-18 10:36:11 +03001276 }
Takashi Iwaia82d51e2012-04-26 12:23:42 +02001277
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 status = azx_readl(chip, INTSTS);
1279 if (status == 0) {
1280 spin_unlock(&chip->reg_lock);
1281 return IRQ_NONE;
1282 }
1283
Takashi Iwai07e4ca52005-08-24 14:14:57 +02001284 for (i = 0; i < chip->num_streams; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 azx_dev = &chip->azx_dev[i];
1286 if (status & azx_dev->sd_int_sta_mask) {
Clemens Ladisch9ef04062010-05-25 09:03:40 +02001287 sd_status = azx_sd_readb(azx_dev, SD_STS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
Clemens Ladisch9ef04062010-05-25 09:03:40 +02001289 if (!azx_dev->substream || !azx_dev->running ||
1290 !(sd_status & SD_INT_COMPLETE))
Takashi Iwai9ad593f2008-05-16 12:34:47 +02001291 continue;
1292 /* check whether this IRQ is really acceptable */
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001293 ok = azx_position_ok(chip, azx_dev);
1294 if (ok == 1) {
Takashi Iwai9ad593f2008-05-16 12:34:47 +02001295 azx_dev->irq_pending = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 spin_unlock(&chip->reg_lock);
1297 snd_pcm_period_elapsed(azx_dev->substream);
1298 spin_lock(&chip->reg_lock);
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001299 } else if (ok == 0 && chip->bus && chip->bus->workq) {
Takashi Iwai9ad593f2008-05-16 12:34:47 +02001300 /* bogus IRQ, process it later */
1301 azx_dev->irq_pending = 1;
Takashi Iwai6acaed32009-01-12 10:09:24 +01001302 queue_work(chip->bus->workq,
1303 &chip->irq_pending_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 }
1305 }
1306 }
1307
1308 /* clear rirb int */
1309 status = azx_readb(chip, RIRBSTS);
1310 if (status & RIRB_INT_MASK) {
Takashi Iwai14d34f12010-10-21 09:03:25 +02001311 if (status & RIRB_INT_RESPONSE) {
Takashi Iwai9477c582011-05-25 09:11:37 +02001312 if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY)
Takashi Iwai14d34f12010-10-21 09:03:25 +02001313 udelay(80);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 azx_update_rirb(chip);
Takashi Iwai14d34f12010-10-21 09:03:25 +02001315 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1317 }
1318
1319#if 0
1320 /* clear state status int */
1321 if (azx_readb(chip, STATESTS) & 0x04)
1322 azx_writeb(chip, STATESTS, 0x04);
1323#endif
1324 spin_unlock(&chip->reg_lock);
1325
1326 return IRQ_HANDLED;
1327}
1328
1329
1330/*
Takashi Iwai675f25d2008-06-10 17:53:20 +02001331 * set up a BDL entry
1332 */
Takashi Iwai5ae763b2012-05-08 10:34:08 +02001333static int setup_bdle(struct azx *chip,
1334 struct snd_pcm_substream *substream,
Takashi Iwai675f25d2008-06-10 17:53:20 +02001335 struct azx_dev *azx_dev, u32 **bdlp,
1336 int ofs, int size, int with_ioc)
1337{
Takashi Iwai675f25d2008-06-10 17:53:20 +02001338 u32 *bdl = *bdlp;
1339
1340 while (size > 0) {
1341 dma_addr_t addr;
1342 int chunk;
1343
1344 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
1345 return -EINVAL;
1346
Takashi Iwai77a23f22008-08-21 13:00:13 +02001347 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
Takashi Iwai675f25d2008-06-10 17:53:20 +02001348 /* program the address field of the BDL entry */
1349 bdl[0] = cpu_to_le32((u32)addr);
Takashi Iwai766979e2008-06-13 20:53:56 +02001350 bdl[1] = cpu_to_le32(upper_32_bits(addr));
Takashi Iwai675f25d2008-06-10 17:53:20 +02001351 /* program the size field of the BDL entry */
Takashi Iwaifc4abee2008-07-30 15:13:34 +02001352 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
Takashi Iwai5ae763b2012-05-08 10:34:08 +02001353 /* one BDLE cannot cross 4K boundary on CTHDA chips */
1354 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) {
1355 u32 remain = 0x1000 - (ofs & 0xfff);
1356 if (chunk > remain)
1357 chunk = remain;
1358 }
Takashi Iwai675f25d2008-06-10 17:53:20 +02001359 bdl[2] = cpu_to_le32(chunk);
1360 /* program the IOC to enable interrupt
1361 * only when the whole fragment is processed
1362 */
1363 size -= chunk;
1364 bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01);
1365 bdl += 4;
1366 azx_dev->frags++;
1367 ofs += chunk;
1368 }
1369 *bdlp = bdl;
1370 return ofs;
1371}
1372
1373/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 * set up BDL entries
1375 */
Takashi Iwai555e2192008-06-10 17:53:34 +02001376static int azx_setup_periods(struct azx *chip,
1377 struct snd_pcm_substream *substream,
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001378 struct azx_dev *azx_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379{
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001380 u32 *bdl;
1381 int i, ofs, periods, period_bytes;
Takashi Iwai555e2192008-06-10 17:53:34 +02001382 int pos_adj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384 /* reset BDL address */
1385 azx_sd_writel(azx_dev, SD_BDLPL, 0);
1386 azx_sd_writel(azx_dev, SD_BDLPU, 0);
1387
Takashi Iwai97b71c92009-03-18 15:09:13 +01001388 period_bytes = azx_dev->period_bytes;
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001389 periods = azx_dev->bufsize / period_bytes;
1390
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 /* program the initial BDL entries */
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001392 bdl = (u32 *)azx_dev->bdl.area;
1393 ofs = 0;
1394 azx_dev->frags = 0;
Takashi Iwai555e2192008-06-10 17:53:34 +02001395 pos_adj = bdl_pos_adj[chip->dev_index];
1396 if (pos_adj > 0) {
Takashi Iwai675f25d2008-06-10 17:53:20 +02001397 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwaie785d3d2008-07-15 16:28:43 +02001398 int pos_align = pos_adj;
Takashi Iwai555e2192008-06-10 17:53:34 +02001399 pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
Takashi Iwai675f25d2008-06-10 17:53:20 +02001400 if (!pos_adj)
Takashi Iwaie785d3d2008-07-15 16:28:43 +02001401 pos_adj = pos_align;
1402 else
1403 pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
1404 pos_align;
Takashi Iwai675f25d2008-06-10 17:53:20 +02001405 pos_adj = frames_to_bytes(runtime, pos_adj);
1406 if (pos_adj >= period_bytes) {
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001407 snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
Takashi Iwai555e2192008-06-10 17:53:34 +02001408 bdl_pos_adj[chip->dev_index]);
Takashi Iwai675f25d2008-06-10 17:53:20 +02001409 pos_adj = 0;
1410 } else {
Takashi Iwai5ae763b2012-05-08 10:34:08 +02001411 ofs = setup_bdle(chip, substream, azx_dev,
Clemens Ladisch7bb8fb72010-11-15 10:49:47 +01001412 &bdl, ofs, pos_adj,
1413 !substream->runtime->no_period_wakeup);
Takashi Iwai675f25d2008-06-10 17:53:20 +02001414 if (ofs < 0)
1415 goto error;
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001416 }
Takashi Iwai555e2192008-06-10 17:53:34 +02001417 } else
1418 pos_adj = 0;
Takashi Iwai675f25d2008-06-10 17:53:20 +02001419 for (i = 0; i < periods; i++) {
1420 if (i == periods - 1 && pos_adj)
Takashi Iwai5ae763b2012-05-08 10:34:08 +02001421 ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
Takashi Iwai675f25d2008-06-10 17:53:20 +02001422 period_bytes - pos_adj, 0);
1423 else
Takashi Iwai5ae763b2012-05-08 10:34:08 +02001424 ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
Clemens Ladisch7bb8fb72010-11-15 10:49:47 +01001425 period_bytes,
1426 !substream->runtime->no_period_wakeup);
Takashi Iwai675f25d2008-06-10 17:53:20 +02001427 if (ofs < 0)
1428 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 }
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001430 return 0;
Takashi Iwai675f25d2008-06-10 17:53:20 +02001431
1432 error:
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001433 snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
Takashi Iwai675f25d2008-06-10 17:53:20 +02001434 azx_dev->bufsize, period_bytes);
Takashi Iwai675f25d2008-06-10 17:53:20 +02001435 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436}
1437
Takashi Iwai1dddab42009-03-18 15:15:37 +01001438/* reset stream */
1439static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440{
1441 unsigned char val;
1442 int timeout;
1443
Takashi Iwai1dddab42009-03-18 15:15:37 +01001444 azx_stream_clear(chip, azx_dev);
1445
Takashi Iwaid01ce992007-07-27 16:52:19 +02001446 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
1447 SD_CTL_STREAM_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 udelay(3);
1449 timeout = 300;
1450 while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
1451 --timeout)
1452 ;
1453 val &= ~SD_CTL_STREAM_RESET;
1454 azx_sd_writeb(azx_dev, SD_CTL, val);
1455 udelay(3);
1456
1457 timeout = 300;
1458 /* waiting for hardware to report that the stream is out of reset */
1459 while (((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
1460 --timeout)
1461 ;
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001462
1463 /* reset first position - may not be synced with hw at this time */
1464 *azx_dev->posbuf = 0;
Takashi Iwai1dddab42009-03-18 15:15:37 +01001465}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
Takashi Iwai1dddab42009-03-18 15:15:37 +01001467/*
1468 * set up the SD for streaming
1469 */
1470static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1471{
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001472 unsigned int val;
Takashi Iwai1dddab42009-03-18 15:15:37 +01001473 /* make sure the run bit is zero for SD */
1474 azx_stream_clear(chip, azx_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 /* program the stream_tag */
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001476 val = azx_sd_readl(azx_dev, SD_CTL);
1477 val = (val & ~SD_CTL_STREAM_TAG_MASK) |
1478 (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT);
1479 if (!azx_snoop(chip))
1480 val |= SD_CTL_TRAFFIC_PRIO;
1481 azx_sd_writel(azx_dev, SD_CTL, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
1483 /* program the length of samples in cyclic buffer */
1484 azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize);
1485
1486 /* program the stream format */
1487 /* this value needs to be the same as the one programmed */
1488 azx_sd_writew(azx_dev, SD_FORMAT, azx_dev->format_val);
1489
1490 /* program the stream LVI (last valid index) of the BDL */
1491 azx_sd_writew(azx_dev, SD_LVI, azx_dev->frags - 1);
1492
1493 /* program the BDL address */
1494 /* lower BDL address */
Takashi Iwai4ce107b2008-02-06 14:50:19 +01001495 azx_sd_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 /* upper BDL address */
Takashi Iwai766979e2008-06-13 20:53:56 +02001497 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
Takashi Iwai0be3b5d2005-09-05 17:11:40 +02001499 /* enable the position buffer */
David Henningsson4cb36312010-09-30 10:12:50 +02001500 if (chip->position_fix[0] != POS_FIX_LPIB ||
1501 chip->position_fix[1] != POS_FIX_LPIB) {
Takashi Iwaiee9d6b92008-03-14 15:52:20 +01001502 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1503 azx_writel(chip, DPLBASE,
1504 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
1505 }
Takashi Iwaic74db862005-05-12 14:26:27 +02001506
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 /* set the interrupt enable bits in the descriptor control register */
Takashi Iwaid01ce992007-07-27 16:52:19 +02001508 azx_sd_writel(azx_dev, SD_CTL,
1509 azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 return 0;
1512}
1513
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001514/*
1515 * Probe the given codec address
1516 */
1517static int probe_codec(struct azx *chip, int addr)
1518{
1519 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
1520 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
1521 unsigned int res;
1522
Wu Fengguanga678cde2009-08-01 18:46:46 +08001523 mutex_lock(&chip->bus->cmd_mutex);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001524 chip->probing = 1;
1525 azx_send_cmd(chip->bus, cmd);
Wu Fengguangdeadff12009-08-01 18:45:16 +08001526 res = azx_get_response(chip->bus, addr);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001527 chip->probing = 0;
Wu Fengguanga678cde2009-08-01 18:46:46 +08001528 mutex_unlock(&chip->bus->cmd_mutex);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001529 if (res == -1)
1530 return -EIO;
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001531 snd_printdd(SFX "codec #%d probed OK\n", addr);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001532 return 0;
1533}
1534
Takashi Iwai33fa35e2008-11-06 16:50:40 +01001535static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1536 struct hda_pcm *cpcm);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001537static void azx_stop_chip(struct azx *chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
Takashi Iwai8dd78332009-06-02 01:16:07 +02001539static void azx_bus_reset(struct hda_bus *bus)
1540{
1541 struct azx *chip = bus->private_data;
Takashi Iwai8dd78332009-06-02 01:16:07 +02001542
1543 bus->in_reset = 1;
1544 azx_stop_chip(chip);
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001545 azx_init_chip(chip, 1);
Alexander Beregalov65f75982009-06-04 13:46:16 +04001546#ifdef CONFIG_PM
Takashi Iwai8dd78332009-06-02 01:16:07 +02001547 if (chip->initialized) {
Takashi Iwai01b65bf2011-11-24 14:31:46 +01001548 struct azx_pcm *p;
1549 list_for_each_entry(p, &chip->pcm_list, list)
1550 snd_pcm_suspend_all(p->pcm);
Takashi Iwai8dd78332009-06-02 01:16:07 +02001551 snd_hda_suspend(chip->bus);
1552 snd_hda_resume(chip->bus);
1553 }
Alexander Beregalov65f75982009-06-04 13:46:16 +04001554#endif
Takashi Iwai8dd78332009-06-02 01:16:07 +02001555 bus->in_reset = 0;
1556}
1557
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558/*
1559 * Codec initialization
1560 */
1561
Takashi Iwai2f5983f2008-09-03 16:00:44 +02001562/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
Takashi Iwaia82d51e2012-04-26 12:23:42 +02001563static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] DELAYED_INITDATA_MARK = {
Wei Ni7445dfc2010-03-03 15:05:53 +08001564 [AZX_DRIVER_NVIDIA] = 8,
Kailang Yangf2690022008-05-27 11:44:55 +02001565 [AZX_DRIVER_TERA] = 1,
Takashi Iwaia9995a32007-03-12 21:30:46 +01001566};
1567
Takashi Iwaia82d51e2012-04-26 12:23:42 +02001568static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *model)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569{
1570 struct hda_bus_template bus_temp;
Takashi Iwai34c25352008-10-28 11:38:58 +01001571 int c, codecs, err;
1572 int max_slots;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
1574 memset(&bus_temp, 0, sizeof(bus_temp));
1575 bus_temp.private_data = chip;
1576 bus_temp.modelname = model;
1577 bus_temp.pci = chip->pci;
Takashi Iwai111d3af2006-02-16 18:17:58 +01001578 bus_temp.ops.command = azx_send_cmd;
1579 bus_temp.ops.get_response = azx_get_response;
Takashi Iwai176d5332008-07-30 15:01:44 +02001580 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
Takashi Iwai8dd78332009-06-02 01:16:07 +02001581 bus_temp.ops.bus_reset = azx_bus_reset;
Takashi Iwaicb53c622007-08-10 17:21:45 +02001582#ifdef CONFIG_SND_HDA_POWER_SAVE
Takashi Iwai11cd41b2008-11-28 07:22:18 +01001583 bus_temp.power_save = &power_save;
Takashi Iwaicb53c622007-08-10 17:21:45 +02001584 bus_temp.ops.pm_notify = azx_power_notify;
1585#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
Takashi Iwaid01ce992007-07-27 16:52:19 +02001587 err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
1588 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 return err;
1590
Takashi Iwai9477c582011-05-25 09:11:37 +02001591 if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
1592 snd_printd(SFX "Enable delay in RIRB handling\n");
Wei Nidc9c8e22008-09-26 13:55:56 +08001593 chip->bus->needs_damn_long_delay = 1;
Takashi Iwai9477c582011-05-25 09:11:37 +02001594 }
Wei Nidc9c8e22008-09-26 13:55:56 +08001595
Takashi Iwai34c25352008-10-28 11:38:58 +01001596 codecs = 0;
Takashi Iwai2f5983f2008-09-03 16:00:44 +02001597 max_slots = azx_max_codecs[chip->driver_type];
1598 if (!max_slots)
Wei Ni7445dfc2010-03-03 15:05:53 +08001599 max_slots = AZX_DEFAULT_CODECS;
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001600
1601 /* First try to probe all given codec slots */
1602 for (c = 0; c < max_slots; c++) {
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01001603 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001604 if (probe_codec(chip, c) < 0) {
1605 /* Some BIOSen give you wrong codec addresses
1606 * that don't exist
1607 */
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001608 snd_printk(KERN_WARNING SFX
1609 "Codec #%d probe error; "
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001610 "disabling it...\n", c);
1611 chip->codec_mask &= ~(1 << c);
1612 /* More badly, accessing to a non-existing
1613 * codec often screws up the controller chip,
Paul Menzel24481582010-02-08 20:37:26 +01001614 * and disturbs the further communications.
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001615 * Thus if an error occurs during probing,
1616 * better to reset the controller chip to
1617 * get back to the sanity state.
1618 */
1619 azx_stop_chip(chip);
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01001620 azx_init_chip(chip, 1);
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001621 }
1622 }
1623 }
1624
Takashi Iwaid507cd62011-04-26 15:25:02 +02001625 /* AMD chipsets often cause the communication stalls upon certain
1626 * sequence like the pin-detection. It seems that forcing the synced
1627 * access works around the stall. Grrr...
1628 */
Takashi Iwai9477c582011-05-25 09:11:37 +02001629 if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
1630 snd_printd(SFX "Enable sync_write for stable communication\n");
Takashi Iwaid507cd62011-04-26 15:25:02 +02001631 chip->bus->sync_write = 1;
1632 chip->bus->allow_bus_reset = 1;
1633 }
1634
Takashi Iwai6ce4a3b2008-11-06 17:11:10 +01001635 /* Then create codec instances */
Takashi Iwai34c25352008-10-28 11:38:58 +01001636 for (c = 0; c < max_slots; c++) {
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01001637 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
Takashi Iwaibccad142007-04-24 12:23:53 +02001638 struct hda_codec *codec;
Takashi Iwaia1e21c92009-06-17 09:33:52 +02001639 err = snd_hda_codec_new(chip->bus, c, &codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 if (err < 0)
1641 continue;
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +01001642 codec->beep_mode = chip->beep_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 codecs++;
Takashi Iwai19a982b2007-03-21 15:14:35 +01001644 }
1645 }
1646 if (!codecs) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 snd_printk(KERN_ERR SFX "no codecs initialized\n");
1648 return -ENXIO;
1649 }
Takashi Iwaia1e21c92009-06-17 09:33:52 +02001650 return 0;
1651}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Takashi Iwaia1e21c92009-06-17 09:33:52 +02001653/* configure each codec instance */
1654static int __devinit azx_codec_configure(struct azx *chip)
1655{
1656 struct hda_codec *codec;
1657 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1658 snd_hda_codec_configure(codec);
1659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 return 0;
1661}
1662
1663
1664/*
1665 * PCM support
1666 */
1667
1668/* assign a stream for the PCM */
Wu Fengguangef18bed2009-12-25 13:14:27 +08001669static inline struct azx_dev *
1670azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671{
Takashi Iwai07e4ca52005-08-24 14:14:57 +02001672 int dev, i, nums;
Wu Fengguangef18bed2009-12-25 13:14:27 +08001673 struct azx_dev *res = NULL;
Takashi Iwaid5cf9912011-10-06 10:07:58 +02001674 /* make a non-zero unique key for the substream */
1675 int key = (substream->pcm->device << 16) | (substream->number << 2) |
1676 (substream->stream + 1);
Wu Fengguangef18bed2009-12-25 13:14:27 +08001677
1678 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
Takashi Iwai07e4ca52005-08-24 14:14:57 +02001679 dev = chip->playback_index_offset;
1680 nums = chip->playback_streams;
1681 } else {
1682 dev = chip->capture_index_offset;
1683 nums = chip->capture_streams;
1684 }
1685 for (i = 0; i < nums; i++, dev++)
Takashi Iwaid01ce992007-07-27 16:52:19 +02001686 if (!chip->azx_dev[dev].opened) {
Wu Fengguangef18bed2009-12-25 13:14:27 +08001687 res = &chip->azx_dev[dev];
Takashi Iwaid5cf9912011-10-06 10:07:58 +02001688 if (res->assigned_key == key)
Wu Fengguangef18bed2009-12-25 13:14:27 +08001689 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 }
Wu Fengguangef18bed2009-12-25 13:14:27 +08001691 if (res) {
1692 res->opened = 1;
Takashi Iwaid5cf9912011-10-06 10:07:58 +02001693 res->assigned_key = key;
Wu Fengguangef18bed2009-12-25 13:14:27 +08001694 }
1695 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696}
1697
1698/* release the assigned stream */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001699static inline void azx_release_device(struct azx_dev *azx_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700{
1701 azx_dev->opened = 0;
1702}
1703
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001704static struct snd_pcm_hardware azx_pcm_hw = {
Takashi Iwaid01ce992007-07-27 16:52:19 +02001705 .info = (SNDRV_PCM_INFO_MMAP |
1706 SNDRV_PCM_INFO_INTERLEAVED |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1708 SNDRV_PCM_INFO_MMAP_VALID |
Pavel Machek927fc862006-08-31 17:03:43 +02001709 /* No full-resume yet implemented */
1710 /* SNDRV_PCM_INFO_RESUME |*/
Takashi Iwai850f0e52008-03-18 17:11:05 +01001711 SNDRV_PCM_INFO_PAUSE |
Clemens Ladisch7bb8fb72010-11-15 10:49:47 +01001712 SNDRV_PCM_INFO_SYNC_START |
1713 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1715 .rates = SNDRV_PCM_RATE_48000,
1716 .rate_min = 48000,
1717 .rate_max = 48000,
1718 .channels_min = 2,
1719 .channels_max = 2,
1720 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
1721 .period_bytes_min = 128,
1722 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
1723 .periods_min = 2,
1724 .periods_max = AZX_MAX_FRAG,
1725 .fifo_size = 0,
1726};
1727
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001728static int azx_pcm_open(struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729{
1730 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1731 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001732 struct azx *chip = apcm->chip;
1733 struct azx_dev *azx_dev;
1734 struct snd_pcm_runtime *runtime = substream->runtime;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 unsigned long flags;
1736 int err;
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05001737 int buff_step;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Ingo Molnar62932df2006-01-16 16:34:20 +01001739 mutex_lock(&chip->open_mutex);
Wu Fengguangef18bed2009-12-25 13:14:27 +08001740 azx_dev = azx_assign_device(chip, substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 if (azx_dev == NULL) {
Ingo Molnar62932df2006-01-16 16:34:20 +01001742 mutex_unlock(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 return -EBUSY;
1744 }
1745 runtime->hw = azx_pcm_hw;
1746 runtime->hw.channels_min = hinfo->channels_min;
1747 runtime->hw.channels_max = hinfo->channels_max;
1748 runtime->hw.formats = hinfo->formats;
1749 runtime->hw.rates = hinfo->rates;
1750 snd_pcm_limit_hw_rates(runtime);
1751 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
Takashi Iwai52409aa2012-01-23 17:10:24 +01001752 if (chip->align_buffer_size)
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05001753 /* constrain buffer sizes to be multiple of 128
1754 bytes. This is more efficient in terms of memory
1755 access but isn't required by the HDA spec and
1756 prevents users from specifying exact period/buffer
1757 sizes. For example for 44.1kHz, a period size set
1758 to 20ms will be rounded to 19.59ms. */
1759 buff_step = 128;
1760 else
1761 /* Don't enforce steps on buffer sizes, still need to
1762 be multiple of 4 bytes (HDA spec). Tested on Intel
1763 HDA controllers, may not work on all devices where
1764 option needs to be disabled */
1765 buff_step = 4;
1766
Joachim Deguara5f1545b2007-03-16 15:01:36 +01001767 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05001768 buff_step);
Joachim Deguara5f1545b2007-03-16 15:01:36 +01001769 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05001770 buff_step);
Dylan Reidb4a91cf2012-06-15 19:36:23 -07001771 snd_hda_power_up_d3wait(apcm->codec);
Takashi Iwaid01ce992007-07-27 16:52:19 +02001772 err = hinfo->ops.open(hinfo, apcm->codec, substream);
1773 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 azx_release_device(azx_dev);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001775 snd_hda_power_down(apcm->codec);
Ingo Molnar62932df2006-01-16 16:34:20 +01001776 mutex_unlock(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 return err;
1778 }
Takashi Iwai70d321e2009-07-03 23:06:45 +02001779 snd_pcm_limit_hw_rates(runtime);
Takashi Iwaiaba66532009-07-05 11:44:46 +02001780 /* sanity check */
1781 if (snd_BUG_ON(!runtime->hw.channels_min) ||
1782 snd_BUG_ON(!runtime->hw.channels_max) ||
1783 snd_BUG_ON(!runtime->hw.formats) ||
1784 snd_BUG_ON(!runtime->hw.rates)) {
1785 azx_release_device(azx_dev);
1786 hinfo->ops.close(hinfo, apcm->codec, substream);
1787 snd_hda_power_down(apcm->codec);
1788 mutex_unlock(&chip->open_mutex);
1789 return -EINVAL;
1790 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 spin_lock_irqsave(&chip->reg_lock, flags);
1792 azx_dev->substream = substream;
1793 azx_dev->running = 0;
1794 spin_unlock_irqrestore(&chip->reg_lock, flags);
1795
1796 runtime->private_data = azx_dev;
Takashi Iwai850f0e52008-03-18 17:11:05 +01001797 snd_pcm_set_sync(substream);
Ingo Molnar62932df2006-01-16 16:34:20 +01001798 mutex_unlock(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 return 0;
1800}
1801
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001802static int azx_pcm_close(struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803{
1804 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1805 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001806 struct azx *chip = apcm->chip;
1807 struct azx_dev *azx_dev = get_azx_dev(substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 unsigned long flags;
1809
Ingo Molnar62932df2006-01-16 16:34:20 +01001810 mutex_lock(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 spin_lock_irqsave(&chip->reg_lock, flags);
1812 azx_dev->substream = NULL;
1813 azx_dev->running = 0;
1814 spin_unlock_irqrestore(&chip->reg_lock, flags);
1815 azx_release_device(azx_dev);
1816 hinfo->ops.close(hinfo, apcm->codec, substream);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001817 snd_hda_power_down(apcm->codec);
Ingo Molnar62932df2006-01-16 16:34:20 +01001818 mutex_unlock(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 return 0;
1820}
1821
Takashi Iwaid01ce992007-07-27 16:52:19 +02001822static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
1823 struct snd_pcm_hw_params *hw_params)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824{
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001825 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1826 struct azx *chip = apcm->chip;
1827 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwai97b71c92009-03-18 15:09:13 +01001828 struct azx_dev *azx_dev = get_azx_dev(substream);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001829 int ret;
Takashi Iwai97b71c92009-03-18 15:09:13 +01001830
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001831 mark_runtime_wc(chip, azx_dev, runtime, false);
Takashi Iwai97b71c92009-03-18 15:09:13 +01001832 azx_dev->bufsize = 0;
1833 azx_dev->period_bytes = 0;
1834 azx_dev->format_val = 0;
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001835 ret = snd_pcm_lib_malloc_pages(substream,
Takashi Iwaid01ce992007-07-27 16:52:19 +02001836 params_buffer_bytes(hw_params));
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001837 if (ret < 0)
1838 return ret;
1839 mark_runtime_wc(chip, azx_dev, runtime, true);
1840 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841}
1842
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001843static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844{
1845 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001846 struct azx_dev *azx_dev = get_azx_dev(substream);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001847 struct azx *chip = apcm->chip;
1848 struct snd_pcm_runtime *runtime = substream->runtime;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
1850
1851 /* reset BDL address */
1852 azx_sd_writel(azx_dev, SD_BDLPL, 0);
1853 azx_sd_writel(azx_dev, SD_BDLPU, 0);
1854 azx_sd_writel(azx_dev, SD_CTL, 0);
Takashi Iwai97b71c92009-03-18 15:09:13 +01001855 azx_dev->bufsize = 0;
1856 azx_dev->period_bytes = 0;
1857 azx_dev->format_val = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Takashi Iwaieb541332010-08-06 13:48:11 +02001859 snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Takashi Iwai27fe48d92011-09-28 17:16:09 +02001861 mark_runtime_wc(chip, azx_dev, runtime, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 return snd_pcm_lib_free_pages(substream);
1863}
1864
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001865static int azx_pcm_prepare(struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866{
1867 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001868 struct azx *chip = apcm->chip;
1869 struct azx_dev *azx_dev = get_azx_dev(substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001871 struct snd_pcm_runtime *runtime = substream->runtime;
Takashi Iwai62b7e5e2010-10-22 17:15:47 +02001872 unsigned int bufsize, period_bytes, format_val, stream_tag;
Takashi Iwai97b71c92009-03-18 15:09:13 +01001873 int err;
Stephen Warren7c9359762011-06-01 11:14:17 -06001874 struct hda_spdif_out *spdif =
1875 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
1876 unsigned short ctls = spdif ? spdif->ctls : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001878 azx_stream_reset(chip, azx_dev);
Takashi Iwai97b71c92009-03-18 15:09:13 +01001879 format_val = snd_hda_calc_stream_format(runtime->rate,
1880 runtime->channels,
1881 runtime->format,
Anssi Hannula32c168c2010-08-03 13:28:57 +03001882 hinfo->maxbps,
Stephen Warren7c9359762011-06-01 11:14:17 -06001883 ctls);
Takashi Iwai97b71c92009-03-18 15:09:13 +01001884 if (!format_val) {
Takashi Iwaid01ce992007-07-27 16:52:19 +02001885 snd_printk(KERN_ERR SFX
1886 "invalid format_val, rate=%d, ch=%d, format=%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 runtime->rate, runtime->channels, runtime->format);
1888 return -EINVAL;
1889 }
1890
Takashi Iwai97b71c92009-03-18 15:09:13 +01001891 bufsize = snd_pcm_lib_buffer_bytes(substream);
1892 period_bytes = snd_pcm_lib_period_bytes(substream);
1893
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02001894 snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
Takashi Iwai97b71c92009-03-18 15:09:13 +01001895 bufsize, format_val);
1896
1897 if (bufsize != azx_dev->bufsize ||
1898 period_bytes != azx_dev->period_bytes ||
1899 format_val != azx_dev->format_val) {
1900 azx_dev->bufsize = bufsize;
1901 azx_dev->period_bytes = period_bytes;
1902 azx_dev->format_val = format_val;
1903 err = azx_setup_periods(chip, substream, azx_dev);
1904 if (err < 0)
1905 return err;
1906 }
1907
Jaroslav Kyselae5463722010-05-11 10:21:46 +02001908 /* wallclk has 24Mhz clock source */
1909 azx_dev->period_wallclk = (((runtime->period_size * 24000) /
1910 runtime->rate) * 1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 azx_setup_controller(chip, azx_dev);
1912 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1913 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
1914 else
1915 azx_dev->fifo_size = 0;
1916
Takashi Iwai62b7e5e2010-10-22 17:15:47 +02001917 stream_tag = azx_dev->stream_tag;
1918 /* CA-IBG chips need the playback stream starting from 1 */
Takashi Iwai9477c582011-05-25 09:11:37 +02001919 if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
Takashi Iwai62b7e5e2010-10-22 17:15:47 +02001920 stream_tag > chip->capture_streams)
1921 stream_tag -= chip->capture_streams;
1922 return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
Takashi Iwaieb541332010-08-06 13:48:11 +02001923 azx_dev->format_val, substream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924}
1925
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001926static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927{
1928 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
Takashi Iwaia98f90f2005-11-17 14:59:02 +01001929 struct azx *chip = apcm->chip;
Takashi Iwai850f0e52008-03-18 17:11:05 +01001930 struct azx_dev *azx_dev;
1931 struct snd_pcm_substream *s;
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001932 int rstart = 0, start, nsync = 0, sbits = 0;
Takashi Iwai850f0e52008-03-18 17:11:05 +01001933 int nwait, timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 switch (cmd) {
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02001936 case SNDRV_PCM_TRIGGER_START:
1937 rstart = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1939 case SNDRV_PCM_TRIGGER_RESUME:
Takashi Iwai850f0e52008-03-18 17:11:05 +01001940 start = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 break;
1942 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
Jaroslav Kysela47123192005-08-15 20:53:07 +02001943 case SNDRV_PCM_TRIGGER_SUSPEND:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 case SNDRV_PCM_TRIGGER_STOP:
Takashi Iwai850f0e52008-03-18 17:11:05 +01001945 start = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 break;
1947 default:
Takashi Iwai850f0e52008-03-18 17:11:05 +01001948 return -EINVAL;
1949 }
1950
1951 snd_pcm_group_for_each_entry(s, substream) {
1952 if (s->pcm->card != substream->pcm->card)
1953 continue;
1954 azx_dev = get_azx_dev(s);
1955 sbits |= 1 << azx_dev->index;
1956 nsync++;
1957 snd_pcm_trigger_done(s, substream);
1958 }
1959
1960 spin_lock(&chip->reg_lock);
1961 if (nsync > 1) {
1962 /* first, set SYNC bits of corresponding streams */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02001963 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1964 azx_writel(chip, OLD_SSYNC,
1965 azx_readl(chip, OLD_SSYNC) | sbits);
1966 else
1967 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
Takashi Iwai850f0e52008-03-18 17:11:05 +01001968 }
1969 snd_pcm_group_for_each_entry(s, substream) {
1970 if (s->pcm->card != substream->pcm->card)
1971 continue;
1972 azx_dev = get_azx_dev(s);
Jaroslav Kyselae5463722010-05-11 10:21:46 +02001973 if (start) {
1974 azx_dev->start_wallclk = azx_readl(chip, WALLCLK);
1975 if (!rstart)
1976 azx_dev->start_wallclk -=
1977 azx_dev->period_wallclk;
Takashi Iwai850f0e52008-03-18 17:11:05 +01001978 azx_stream_start(chip, azx_dev);
Jaroslav Kyselae5463722010-05-11 10:21:46 +02001979 } else {
Takashi Iwai850f0e52008-03-18 17:11:05 +01001980 azx_stream_stop(chip, azx_dev);
Jaroslav Kyselae5463722010-05-11 10:21:46 +02001981 }
Takashi Iwai850f0e52008-03-18 17:11:05 +01001982 azx_dev->running = start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 }
1984 spin_unlock(&chip->reg_lock);
Takashi Iwai850f0e52008-03-18 17:11:05 +01001985 if (start) {
1986 if (nsync == 1)
1987 return 0;
1988 /* wait until all FIFOs get ready */
1989 for (timeout = 5000; timeout; timeout--) {
1990 nwait = 0;
1991 snd_pcm_group_for_each_entry(s, substream) {
1992 if (s->pcm->card != substream->pcm->card)
1993 continue;
1994 azx_dev = get_azx_dev(s);
1995 if (!(azx_sd_readb(azx_dev, SD_STS) &
1996 SD_STS_FIFO_READY))
1997 nwait++;
1998 }
1999 if (!nwait)
2000 break;
2001 cpu_relax();
2002 }
2003 } else {
2004 /* wait until all RUN bits are cleared */
2005 for (timeout = 5000; timeout; timeout--) {
2006 nwait = 0;
2007 snd_pcm_group_for_each_entry(s, substream) {
2008 if (s->pcm->card != substream->pcm->card)
2009 continue;
2010 azx_dev = get_azx_dev(s);
2011 if (azx_sd_readb(azx_dev, SD_CTL) &
2012 SD_CTL_DMA_START)
2013 nwait++;
2014 }
2015 if (!nwait)
2016 break;
2017 cpu_relax();
2018 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 }
Takashi Iwai850f0e52008-03-18 17:11:05 +01002020 if (nsync > 1) {
2021 spin_lock(&chip->reg_lock);
2022 /* reset SYNC bits */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02002023 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
2024 azx_writel(chip, OLD_SSYNC,
2025 azx_readl(chip, OLD_SSYNC) & ~sbits);
2026 else
2027 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
Takashi Iwai850f0e52008-03-18 17:11:05 +01002028 spin_unlock(&chip->reg_lock);
2029 }
2030 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031}
2032
Joseph Chan0e153472008-08-26 14:38:03 +02002033/* get the current DMA position with correction on VIA chips */
2034static unsigned int azx_via_get_position(struct azx *chip,
2035 struct azx_dev *azx_dev)
2036{
2037 unsigned int link_pos, mini_pos, bound_pos;
2038 unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
2039 unsigned int fifo_size;
2040
2041 link_pos = azx_sd_readl(azx_dev, SD_LPIB);
Takashi Iwaib4a655e2011-06-07 12:26:56 +02002042 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
Joseph Chan0e153472008-08-26 14:38:03 +02002043 /* Playback, no problem using link position */
2044 return link_pos;
2045 }
2046
2047 /* Capture */
2048 /* For new chipset,
2049 * use mod to get the DMA position just like old chipset
2050 */
2051 mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
2052 mod_dma_pos %= azx_dev->period_bytes;
2053
2054 /* azx_dev->fifo_size can't get FIFO size of in stream.
2055 * Get from base address + offset.
2056 */
2057 fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
2058
2059 if (azx_dev->insufficient) {
2060 /* Link position never gather than FIFO size */
2061 if (link_pos <= fifo_size)
2062 return 0;
2063
2064 azx_dev->insufficient = 0;
2065 }
2066
2067 if (link_pos <= fifo_size)
2068 mini_pos = azx_dev->bufsize + link_pos - fifo_size;
2069 else
2070 mini_pos = link_pos - fifo_size;
2071
2072 /* Find nearest previous boudary */
2073 mod_mini_pos = mini_pos % azx_dev->period_bytes;
2074 mod_link_pos = link_pos % azx_dev->period_bytes;
2075 if (mod_link_pos >= fifo_size)
2076 bound_pos = link_pos - mod_link_pos;
2077 else if (mod_dma_pos >= mod_mini_pos)
2078 bound_pos = mini_pos - mod_mini_pos;
2079 else {
2080 bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
2081 if (bound_pos >= azx_dev->bufsize)
2082 bound_pos = 0;
2083 }
2084
2085 /* Calculate real DMA position we want */
2086 return bound_pos + mod_dma_pos;
2087}
2088
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002089static unsigned int azx_get_position(struct azx *chip,
Takashi Iwai798cb7e2011-09-30 08:52:26 +02002090 struct azx_dev *azx_dev,
2091 bool with_check)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 unsigned int pos;
David Henningsson4cb36312010-09-30 10:12:50 +02002094 int stream = azx_dev->substream->stream;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095
David Henningsson4cb36312010-09-30 10:12:50 +02002096 switch (chip->position_fix[stream]) {
2097 case POS_FIX_LPIB:
2098 /* read LPIB */
2099 pos = azx_sd_readl(azx_dev, SD_LPIB);
2100 break;
2101 case POS_FIX_VIACOMBO:
Joseph Chan0e153472008-08-26 14:38:03 +02002102 pos = azx_via_get_position(chip, azx_dev);
David Henningsson4cb36312010-09-30 10:12:50 +02002103 break;
2104 default:
2105 /* use the position buffer */
2106 pos = le32_to_cpu(*azx_dev->posbuf);
Takashi Iwai798cb7e2011-09-30 08:52:26 +02002107 if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) {
Takashi Iwaia8103642011-06-07 12:23:23 +02002108 if (!pos || pos == (u32)-1) {
2109 printk(KERN_WARNING
2110 "hda-intel: Invalid position buffer, "
2111 "using LPIB read method instead.\n");
2112 chip->position_fix[stream] = POS_FIX_LPIB;
2113 pos = azx_sd_readl(azx_dev, SD_LPIB);
2114 } else
2115 chip->position_fix[stream] = POS_FIX_POSBUF;
2116 }
2117 break;
Takashi Iwaic74db862005-05-12 14:26:27 +02002118 }
David Henningsson4cb36312010-09-30 10:12:50 +02002119
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 if (pos >= azx_dev->bufsize)
2121 pos = 0;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002122 return pos;
2123}
2124
2125static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
2126{
2127 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
2128 struct azx *chip = apcm->chip;
2129 struct azx_dev *azx_dev = get_azx_dev(substream);
2130 return bytes_to_frames(substream->runtime,
Takashi Iwai798cb7e2011-09-30 08:52:26 +02002131 azx_get_position(chip, azx_dev, false));
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002132}
2133
2134/*
2135 * Check whether the current DMA position is acceptable for updating
2136 * periods. Returns non-zero if it's OK.
2137 *
2138 * Many HD-audio controllers appear pretty inaccurate about
2139 * the update-IRQ timing. The IRQ is issued before actually the
2140 * data is processed. So, we need to process it afterwords in a
2141 * workqueue.
2142 */
2143static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
2144{
Jaroslav Kyselae5463722010-05-11 10:21:46 +02002145 u32 wallclk;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002146 unsigned int pos;
Shahin Ghazinouribeaffc32010-05-11 08:19:55 +02002147 int stream;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002148
Jaroslav Kyselaf48f6062010-05-11 12:10:47 +02002149 wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
2150 if (wallclk < (azx_dev->period_wallclk * 2) / 3)
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02002151 return -1; /* bogus (too early) interrupt */
Jaroslav Kyselafa00e042009-04-10 12:20:45 +02002152
Shahin Ghazinouribeaffc32010-05-11 08:19:55 +02002153 stream = azx_dev->substream->stream;
Takashi Iwai798cb7e2011-09-30 08:52:26 +02002154 pos = azx_get_position(chip, azx_dev, true);
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002155
Takashi Iwaid6d8bf52010-02-12 18:17:06 +01002156 if (WARN_ONCE(!azx_dev->period_bytes,
2157 "hda-intel: zero azx_dev->period_bytes"))
Jaroslav Kyselaf48f6062010-05-11 12:10:47 +02002158 return -1; /* this shouldn't happen! */
Jaroslav Kyselaedb39932010-06-02 13:29:17 +02002159 if (wallclk < (azx_dev->period_wallclk * 5) / 4 &&
Jaroslav Kyselaf48f6062010-05-11 12:10:47 +02002160 pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
2161 /* NG - it's below the first next period boundary */
2162 return bdl_pos_adj[chip->dev_index] ? 0 : -1;
Jaroslav Kyselaedb39932010-06-02 13:29:17 +02002163 azx_dev->start_wallclk += wallclk;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002164 return 1; /* OK, it's fine */
2165}
2166
2167/*
2168 * The work for pending PCM period updates.
2169 */
2170static void azx_irq_pending_work(struct work_struct *work)
2171{
2172 struct azx *chip = container_of(work, struct azx, irq_pending_work);
Jaroslav Kyselae5463722010-05-11 10:21:46 +02002173 int i, pending, ok;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002174
Takashi Iwaia6a950a2008-06-10 17:53:35 +02002175 if (!chip->irq_pending_warned) {
2176 printk(KERN_WARNING
2177 "hda-intel: IRQ timing workaround is activated "
2178 "for card #%d. Suggest a bigger bdl_pos_adj.\n",
2179 chip->card->number);
2180 chip->irq_pending_warned = 1;
2181 }
2182
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002183 for (;;) {
2184 pending = 0;
2185 spin_lock_irq(&chip->reg_lock);
2186 for (i = 0; i < chip->num_streams; i++) {
2187 struct azx_dev *azx_dev = &chip->azx_dev[i];
2188 if (!azx_dev->irq_pending ||
2189 !azx_dev->substream ||
2190 !azx_dev->running)
2191 continue;
Jaroslav Kyselae5463722010-05-11 10:21:46 +02002192 ok = azx_position_ok(chip, azx_dev);
2193 if (ok > 0) {
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002194 azx_dev->irq_pending = 0;
2195 spin_unlock(&chip->reg_lock);
2196 snd_pcm_period_elapsed(azx_dev->substream);
2197 spin_lock(&chip->reg_lock);
Jaroslav Kyselae5463722010-05-11 10:21:46 +02002198 } else if (ok < 0) {
2199 pending = 0; /* too early */
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002200 } else
2201 pending++;
2202 }
2203 spin_unlock_irq(&chip->reg_lock);
2204 if (!pending)
2205 return;
Takashi Iwai08af4952010-08-03 14:39:04 +02002206 msleep(1);
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002207 }
2208}
2209
2210/* clear irq_pending flags and assure no on-going workq */
2211static void azx_clear_irq_pending(struct azx *chip)
2212{
2213 int i;
2214
2215 spin_lock_irq(&chip->reg_lock);
2216 for (i = 0; i < chip->num_streams; i++)
2217 chip->azx_dev[i].irq_pending = 0;
2218 spin_unlock_irq(&chip->reg_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219}
2220
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002221#ifdef CONFIG_X86
2222static int azx_pcm_mmap(struct snd_pcm_substream *substream,
2223 struct vm_area_struct *area)
2224{
2225 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
2226 struct azx *chip = apcm->chip;
2227 if (!azx_snoop(chip))
2228 area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
2229 return snd_pcm_lib_default_mmap(substream, area);
2230}
2231#else
2232#define azx_pcm_mmap NULL
2233#endif
2234
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002235static struct snd_pcm_ops azx_pcm_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 .open = azx_pcm_open,
2237 .close = azx_pcm_close,
2238 .ioctl = snd_pcm_lib_ioctl,
2239 .hw_params = azx_pcm_hw_params,
2240 .hw_free = azx_pcm_hw_free,
2241 .prepare = azx_pcm_prepare,
2242 .trigger = azx_pcm_trigger,
2243 .pointer = azx_pcm_pointer,
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002244 .mmap = azx_pcm_mmap,
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002245 .page = snd_pcm_sgbuf_ops_page,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246};
2247
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002248static void azx_pcm_free(struct snd_pcm *pcm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249{
Takashi Iwai176d5332008-07-30 15:01:44 +02002250 struct azx_pcm *apcm = pcm->private_data;
2251 if (apcm) {
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002252 list_del(&apcm->list);
Takashi Iwai176d5332008-07-30 15:01:44 +02002253 kfree(apcm);
2254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255}
2256
Takashi Iwaiacfa6342011-07-12 17:27:46 +02002257#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
2258
Takashi Iwai176d5332008-07-30 15:01:44 +02002259static int
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002260azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2261 struct hda_pcm *cpcm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002263 struct azx *chip = bus->private_data;
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002264 struct snd_pcm *pcm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 struct azx_pcm *apcm;
Takashi Iwai176d5332008-07-30 15:01:44 +02002266 int pcm_dev = cpcm->device;
Takashi Iwaiacfa6342011-07-12 17:27:46 +02002267 unsigned int size;
Takashi Iwai176d5332008-07-30 15:01:44 +02002268 int s, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002270 list_for_each_entry(apcm, &chip->pcm_list, list) {
2271 if (apcm->pcm->device == pcm_dev) {
2272 snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
2273 return -EBUSY;
2274 }
Takashi Iwai176d5332008-07-30 15:01:44 +02002275 }
2276 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
2277 cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
2278 cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 &pcm);
2280 if (err < 0)
2281 return err;
Takashi Iwai18cb7102009-04-16 10:22:24 +02002282 strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
Takashi Iwai176d5332008-07-30 15:01:44 +02002283 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 if (apcm == NULL)
2285 return -ENOMEM;
2286 apcm->chip = chip;
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002287 apcm->pcm = pcm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 apcm->codec = codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 pcm->private_data = apcm;
2290 pcm->private_free = azx_pcm_free;
Takashi Iwai176d5332008-07-30 15:01:44 +02002291 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
2292 pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002293 list_add_tail(&apcm->list, &chip->pcm_list);
Takashi Iwai176d5332008-07-30 15:01:44 +02002294 cpcm->pcm = pcm;
2295 for (s = 0; s < 2; s++) {
2296 apcm->hinfo[s] = &cpcm->stream[s];
2297 if (cpcm->stream[s].substreams)
2298 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
2299 }
2300 /* buffer pre-allocation */
Takashi Iwaiacfa6342011-07-12 17:27:46 +02002301 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
2302 if (size > MAX_PREALLOC_SIZE)
2303 size = MAX_PREALLOC_SIZE;
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002304 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 snd_dma_pci_data(chip->pci),
Takashi Iwaiacfa6342011-07-12 17:27:46 +02002306 size, MAX_PREALLOC_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307 return 0;
2308}
2309
2310/*
2311 * mixer creation - all stuff is implemented in hda module
2312 */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002313static int __devinit azx_mixer_create(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314{
2315 return snd_hda_build_controls(chip->bus);
2316}
2317
2318
2319/*
2320 * initialize SD streams
2321 */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002322static int __devinit azx_init_stream(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323{
2324 int i;
2325
2326 /* initialize each stream (aka device)
Takashi Iwaid01ce992007-07-27 16:52:19 +02002327 * assign the starting bdl address to each stream (device)
2328 * and initialize
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 */
Takashi Iwai07e4ca52005-08-24 14:14:57 +02002330 for (i = 0; i < chip->num_streams; i++) {
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002331 struct azx_dev *azx_dev = &chip->azx_dev[i];
Takashi Iwai929861c2006-08-31 16:55:40 +02002332 azx_dev->posbuf = (u32 __iomem *)(chip->posbuf.area + i * 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
2334 azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
2335 /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
2336 azx_dev->sd_int_sta_mask = 1 << i;
2337 /* stream tag: must be non-zero and unique */
2338 azx_dev->index = i;
2339 azx_dev->stream_tag = i + 1;
2340 }
2341
2342 return 0;
2343}
2344
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002345static int azx_acquire_irq(struct azx *chip, int do_disconnect)
2346{
Takashi Iwai437a5a42006-11-21 12:14:23 +01002347 if (request_irq(chip->pci->irq, azx_interrupt,
2348 chip->msi ? 0 : IRQF_SHARED,
Takashi Iwai934c2b62011-06-10 16:36:37 +02002349 KBUILD_MODNAME, chip)) {
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002350 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
2351 "disabling device\n", chip->pci->irq);
2352 if (do_disconnect)
2353 snd_card_disconnect(chip->card);
2354 return -1;
2355 }
2356 chip->irq = chip->pci->irq;
Takashi Iwai69e13412006-11-21 12:10:55 +01002357 pci_intx(chip->pci, !chip->msi);
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002358 return 0;
2359}
2360
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361
Takashi Iwaicb53c622007-08-10 17:21:45 +02002362static void azx_stop_chip(struct azx *chip)
2363{
Takashi Iwai95e99fd2007-08-13 15:29:04 +02002364 if (!chip->initialized)
Takashi Iwaicb53c622007-08-10 17:21:45 +02002365 return;
2366
2367 /* disable interrupts */
2368 azx_int_disable(chip);
2369 azx_int_clear(chip);
2370
2371 /* disable CORB/RIRB */
2372 azx_free_cmd_io(chip);
2373
2374 /* disable position buffer */
2375 azx_writel(chip, DPLBASE, 0);
2376 azx_writel(chip, DPUBASE, 0);
2377
2378 chip->initialized = 0;
2379}
2380
2381#ifdef CONFIG_SND_HDA_POWER_SAVE
2382/* power-up/down the controller */
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002383static void azx_power_notify(struct hda_bus *bus)
Takashi Iwaicb53c622007-08-10 17:21:45 +02002384{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002385 struct azx *chip = bus->private_data;
Takashi Iwaicb53c622007-08-10 17:21:45 +02002386 struct hda_codec *c;
2387 int power_on = 0;
2388
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002389 list_for_each_entry(c, &bus->codec_list, list) {
Takashi Iwaicb53c622007-08-10 17:21:45 +02002390 if (c->power_on) {
2391 power_on = 1;
2392 break;
2393 }
2394 }
2395 if (power_on)
Jaroslav Kyselacd508fe2010-03-26 10:28:46 +01002396 azx_init_chip(chip, 1);
Wu Fengguang0287d972009-12-11 20:15:11 +08002397 else if (chip->running && power_save_controller &&
2398 !bus->power_keep_link_on)
Takashi Iwaicb53c622007-08-10 17:21:45 +02002399 azx_stop_chip(chip);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002400}
Takashi Iwai5c0b9be2008-12-11 11:47:17 +01002401#endif /* CONFIG_SND_HDA_POWER_SAVE */
2402
2403#ifdef CONFIG_PM
2404/*
2405 * power management
2406 */
Takashi Iwai986862bd2008-11-27 12:40:13 +01002407
Takashi Iwai421a1252005-11-17 16:11:09 +01002408static int azx_suspend(struct pci_dev *pci, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409{
Takashi Iwai421a1252005-11-17 16:11:09 +01002410 struct snd_card *card = pci_get_drvdata(pci);
2411 struct azx *chip = card->private_data;
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002412 struct azx_pcm *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413
Takashi Iwai421a1252005-11-17 16:11:09 +01002414 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002415 azx_clear_irq_pending(chip);
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002416 list_for_each_entry(p, &chip->pcm_list, list)
2417 snd_pcm_suspend_all(p->pcm);
Takashi Iwai0b7a2e92007-08-14 15:18:26 +02002418 if (chip->initialized)
Takashi Iwai8dd78332009-06-02 01:16:07 +02002419 snd_hda_suspend(chip->bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002420 azx_stop_chip(chip);
Takashi Iwai30b35392006-10-11 18:52:53 +02002421 if (chip->irq >= 0) {
Takashi Iwai43001c92006-09-08 12:30:03 +02002422 free_irq(chip->irq, chip);
Takashi Iwai30b35392006-10-11 18:52:53 +02002423 chip->irq = -1;
2424 }
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002425 if (chip->msi)
Takashi Iwai43001c92006-09-08 12:30:03 +02002426 pci_disable_msi(chip->pci);
Takashi Iwai421a1252005-11-17 16:11:09 +01002427 pci_disable_device(pci);
2428 pci_save_state(pci);
Takashi Iwai30b35392006-10-11 18:52:53 +02002429 pci_set_power_state(pci, pci_choose_state(pci, state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430 return 0;
2431}
2432
Takashi Iwai421a1252005-11-17 16:11:09 +01002433static int azx_resume(struct pci_dev *pci)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434{
Takashi Iwai421a1252005-11-17 16:11:09 +01002435 struct snd_card *card = pci_get_drvdata(pci);
2436 struct azx *chip = card->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
Takashi Iwaid14a7e02009-02-16 10:13:03 +01002438 pci_set_power_state(pci, PCI_D0);
2439 pci_restore_state(pci);
Takashi Iwai30b35392006-10-11 18:52:53 +02002440 if (pci_enable_device(pci) < 0) {
2441 printk(KERN_ERR "hda-intel: pci_enable_device failed, "
2442 "disabling device\n");
2443 snd_card_disconnect(card);
2444 return -EIO;
2445 }
2446 pci_set_master(pci);
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002447 if (chip->msi)
2448 if (pci_enable_msi(pci) < 0)
2449 chip->msi = 0;
2450 if (azx_acquire_irq(chip, 1) < 0)
Takashi Iwai30b35392006-10-11 18:52:53 +02002451 return -EIO;
Takashi Iwaicb53c622007-08-10 17:21:45 +02002452 azx_init_pci(chip);
Maxim Levitskyd804ad92007-09-03 15:28:04 +02002453
Takashi Iwai7f308302012-05-08 16:52:23 +02002454 azx_init_chip(chip, 1);
Maxim Levitskyd804ad92007-09-03 15:28:04 +02002455
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 snd_hda_resume(chip->bus);
Takashi Iwai421a1252005-11-17 16:11:09 +01002457 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 return 0;
2459}
2460#endif /* CONFIG_PM */
2461
2462
2463/*
Takashi Iwai0cbf0092008-10-29 16:18:25 +01002464 * reboot notifier for hang-up problem at power-down
2465 */
2466static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
2467{
2468 struct azx *chip = container_of(nb, struct azx, reboot_notifier);
Takashi Iwaifb8d1a32009-11-10 16:02:29 +01002469 snd_hda_bus_reboot_notify(chip->bus);
Takashi Iwai0cbf0092008-10-29 16:18:25 +01002470 azx_stop_chip(chip);
2471 return NOTIFY_OK;
2472}
2473
2474static void azx_notifier_register(struct azx *chip)
2475{
2476 chip->reboot_notifier.notifier_call = azx_halt;
2477 register_reboot_notifier(&chip->reboot_notifier);
2478}
2479
2480static void azx_notifier_unregister(struct azx *chip)
2481{
2482 if (chip->reboot_notifier.notifier_call)
2483 unregister_reboot_notifier(&chip->reboot_notifier);
2484}
2485
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002486static int DELAYED_INIT_MARK azx_first_init(struct azx *chip);
2487static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip);
2488
Steven Newbury8393ec4a2012-06-08 13:06:29 +02002489#ifdef SUPPORT_VGA_SWITCHEROO
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002490static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci);
2491
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002492static void azx_vs_set_state(struct pci_dev *pci,
2493 enum vga_switcheroo_state state)
2494{
2495 struct snd_card *card = pci_get_drvdata(pci);
2496 struct azx *chip = card->private_data;
2497 bool disabled;
2498
2499 if (chip->init_failed)
2500 return;
2501
2502 disabled = (state == VGA_SWITCHEROO_OFF);
2503 if (chip->disabled == disabled)
2504 return;
2505
2506 if (!chip->bus) {
2507 chip->disabled = disabled;
2508 if (!disabled) {
2509 snd_printk(KERN_INFO SFX
2510 "%s: Start delayed initialization\n",
2511 pci_name(chip->pci));
2512 if (azx_first_init(chip) < 0 ||
2513 azx_probe_continue(chip) < 0) {
2514 snd_printk(KERN_ERR SFX
2515 "%s: initialization error\n",
2516 pci_name(chip->pci));
2517 chip->init_failed = true;
2518 }
2519 }
2520 } else {
2521 snd_printk(KERN_INFO SFX
2522 "%s %s via VGA-switcheroo\n",
2523 disabled ? "Disabling" : "Enabling",
2524 pci_name(chip->pci));
2525 if (disabled) {
2526 azx_suspend(pci, PMSG_FREEZE);
2527 chip->disabled = true;
2528 snd_hda_lock_devices(chip->bus);
2529 } else {
2530 snd_hda_unlock_devices(chip->bus);
2531 chip->disabled = false;
2532 azx_resume(pci);
2533 }
2534 }
2535}
2536
2537static bool azx_vs_can_switch(struct pci_dev *pci)
2538{
2539 struct snd_card *card = pci_get_drvdata(pci);
2540 struct azx *chip = card->private_data;
2541
2542 if (chip->init_failed)
2543 return false;
2544 if (chip->disabled || !chip->bus)
2545 return true;
2546 if (snd_hda_lock_devices(chip->bus))
2547 return false;
2548 snd_hda_unlock_devices(chip->bus);
2549 return true;
2550}
2551
2552static void __devinit init_vga_switcheroo(struct azx *chip)
2553{
2554 struct pci_dev *p = get_bound_vga(chip->pci);
2555 if (p) {
2556 snd_printk(KERN_INFO SFX
2557 "%s: Handle VGA-switcheroo audio client\n",
2558 pci_name(chip->pci));
2559 chip->use_vga_switcheroo = 1;
2560 pci_dev_put(p);
2561 }
2562}
2563
2564static const struct vga_switcheroo_client_ops azx_vs_ops = {
2565 .set_gpu_state = azx_vs_set_state,
2566 .can_switch = azx_vs_can_switch,
2567};
2568
2569static int __devinit register_vga_switcheroo(struct azx *chip)
2570{
2571 if (!chip->use_vga_switcheroo)
2572 return 0;
2573 /* FIXME: currently only handling DIS controller
2574 * is there any machine with two switchable HDMI audio controllers?
2575 */
2576 return vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops,
2577 VGA_SWITCHEROO_DIS,
2578 chip->bus != NULL);
2579}
2580#else
2581#define init_vga_switcheroo(chip) /* NOP */
2582#define register_vga_switcheroo(chip) 0
Steven Newbury8393ec4a2012-06-08 13:06:29 +02002583#define check_hdmi_disabled(pci) false
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002584#endif /* SUPPORT_VGA_SWITCHER */
2585
Takashi Iwai0cbf0092008-10-29 16:18:25 +01002586/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 * destructor
2588 */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002589static int azx_free(struct azx *chip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590{
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002591 int i;
2592
Takashi Iwai0cbf0092008-10-29 16:18:25 +01002593 azx_notifier_unregister(chip);
2594
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002595 if (use_vga_switcheroo(chip)) {
2596 if (chip->disabled && chip->bus)
2597 snd_hda_unlock_devices(chip->bus);
2598 vga_switcheroo_unregister_client(chip->pci);
2599 }
2600
Takashi Iwaice43fba2005-05-30 20:33:44 +02002601 if (chip->initialized) {
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002602 azx_clear_irq_pending(chip);
Takashi Iwai07e4ca52005-08-24 14:14:57 +02002603 for (i = 0; i < chip->num_streams; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 azx_stream_stop(chip, &chip->azx_dev[i]);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002605 azx_stop_chip(chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 }
2607
Jeff Garzikf000fd82008-04-22 13:50:34 +02002608 if (chip->irq >= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 free_irq(chip->irq, (void*)chip);
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002610 if (chip->msi)
Takashi Iwai30b35392006-10-11 18:52:53 +02002611 pci_disable_msi(chip->pci);
Takashi Iwaif079c252006-06-01 11:42:14 +02002612 if (chip->remap_addr)
2613 iounmap(chip->remap_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002615 if (chip->azx_dev) {
2616 for (i = 0; i < chip->num_streams; i++)
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002617 if (chip->azx_dev[i].bdl.area) {
2618 mark_pages_wc(chip, &chip->azx_dev[i].bdl, false);
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002619 snd_dma_free_pages(&chip->azx_dev[i].bdl);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002620 }
Takashi Iwai4ce107b2008-02-06 14:50:19 +01002621 }
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002622 if (chip->rb.area) {
2623 mark_pages_wc(chip, &chip->rb, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 snd_dma_free_pages(&chip->rb);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002625 }
2626 if (chip->posbuf.area) {
2627 mark_pages_wc(chip, &chip->posbuf, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 snd_dma_free_pages(&chip->posbuf);
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002629 }
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002630 if (chip->region_requested)
2631 pci_release_regions(chip->pci);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632 pci_disable_device(chip->pci);
Takashi Iwai07e4ca52005-08-24 14:14:57 +02002633 kfree(chip->azx_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 kfree(chip);
2635
2636 return 0;
2637}
2638
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002639static int azx_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640{
2641 return azx_free(device->device_data);
2642}
2643
Steven Newbury8393ec4a2012-06-08 13:06:29 +02002644#ifdef SUPPORT_VGA_SWITCHEROO
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645/*
Takashi Iwai91219472012-04-26 12:13:25 +02002646 * Check of disabled HDMI controller by vga-switcheroo
2647 */
2648static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci)
2649{
2650 struct pci_dev *p;
2651
2652 /* check only discrete GPU */
2653 switch (pci->vendor) {
2654 case PCI_VENDOR_ID_ATI:
2655 case PCI_VENDOR_ID_AMD:
2656 case PCI_VENDOR_ID_NVIDIA:
2657 if (pci->devfn == 1) {
2658 p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
2659 pci->bus->number, 0);
2660 if (p) {
2661 if ((p->class >> 8) == PCI_CLASS_DISPLAY_VGA)
2662 return p;
2663 pci_dev_put(p);
2664 }
2665 }
2666 break;
2667 }
2668 return NULL;
2669}
2670
2671static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
2672{
2673 bool vga_inactive = false;
2674 struct pci_dev *p = get_bound_vga(pci);
2675
2676 if (p) {
Takashi Iwai12b78a72012-06-07 12:15:16 +02002677 if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
Takashi Iwai91219472012-04-26 12:13:25 +02002678 vga_inactive = true;
2679 pci_dev_put(p);
2680 }
2681 return vga_inactive;
2682}
Steven Newbury8393ec4a2012-06-08 13:06:29 +02002683#endif /* SUPPORT_VGA_SWITCHEROO */
Takashi Iwai91219472012-04-26 12:13:25 +02002684
2685/*
Takashi Iwai3372a152007-02-01 15:46:50 +01002686 * white/black-listing for position_fix
2687 */
Ralf Baechle623ec042007-03-13 15:29:47 +01002688static struct snd_pci_quirk position_fix_list[] __devinitdata = {
Takashi Iwaid2e1c972008-06-10 17:53:34 +02002689 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2690 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
Takashi Iwai2f703e72009-12-01 14:17:37 +01002691 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
Takashi Iwaid2e1c972008-06-10 17:53:34 +02002692 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
Daniel T Chendd37f8e2010-05-30 01:17:03 -04002693 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
Daniel T Chen9f75c1b2010-05-30 13:08:41 -04002694 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
Daniel T Chene96d3122010-05-27 18:32:18 -04002695 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
David Henningssonb01de4f2012-01-12 16:31:14 +01002696 SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
Daniel T Chen61bb42c2010-05-29 11:04:11 -04002697 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
Daniel T Chen9ec8dda2010-03-28 02:34:40 -04002698 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
Takashi Iwai45d4ebf2009-11-30 11:58:30 +01002699 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
Takashi Iwai8815cd02010-04-15 09:02:41 +02002700 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
Daniel T Chenb90c0762010-05-30 19:31:41 -04002701 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
Daniel T Chen0e0280d2010-04-21 19:55:43 -04002702 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
Takashi Iwai3372a152007-02-01 15:46:50 +01002703 {}
2704};
2705
2706static int __devinit check_position_fix(struct azx *chip, int fix)
2707{
2708 const struct snd_pci_quirk *q;
2709
Takashi Iwaic673ba12009-03-17 07:49:14 +01002710 switch (fix) {
2711 case POS_FIX_LPIB:
2712 case POS_FIX_POSBUF:
David Henningsson4cb36312010-09-30 10:12:50 +02002713 case POS_FIX_VIACOMBO:
Takashi Iwaia6f2fd52012-02-28 11:58:40 +01002714 case POS_FIX_COMBO:
Takashi Iwaic673ba12009-03-17 07:49:14 +01002715 return fix;
2716 }
2717
Takashi Iwaic673ba12009-03-17 07:49:14 +01002718 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
2719 if (q) {
2720 printk(KERN_INFO
2721 "hda_intel: position_fix set to %d "
2722 "for device %04x:%04x\n",
2723 q->value, q->subvendor, q->subdevice);
2724 return q->value;
Takashi Iwai3372a152007-02-01 15:46:50 +01002725 }
David Henningssonbdd9ef22010-10-04 12:02:14 +02002726
2727 /* Check VIA/ATI HD Audio Controller exist */
Takashi Iwai9477c582011-05-25 09:11:37 +02002728 if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
2729 snd_printd(SFX "Using VIACOMBO position fix\n");
David Henningssonbdd9ef22010-10-04 12:02:14 +02002730 return POS_FIX_VIACOMBO;
2731 }
Takashi Iwai9477c582011-05-25 09:11:37 +02002732 if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
2733 snd_printd(SFX "Using LPIB position fix\n");
2734 return POS_FIX_LPIB;
2735 }
Seth Heasleyc20c5a82012-06-14 14:23:53 -07002736 if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
2737 snd_printd(SFX "Using COMBO position fix\n");
2738 return POS_FIX_COMBO;
2739 }
Takashi Iwaic673ba12009-03-17 07:49:14 +01002740 return POS_FIX_AUTO;
Takashi Iwai3372a152007-02-01 15:46:50 +01002741}
2742
2743/*
Takashi Iwai669ba272007-08-17 09:17:36 +02002744 * black-lists for probe_mask
2745 */
2746static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
2747 /* Thinkpad often breaks the controller communication when accessing
2748 * to the non-working (or non-existing) modem codec slot.
2749 */
2750 SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
2751 SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
2752 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
Takashi Iwai0edb9452008-11-07 14:53:09 +01002753 /* broken BIOS */
2754 SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
Takashi Iwaief1681d2008-11-24 17:29:28 +01002755 /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
2756 SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
Takashi Iwai20db7cb2009-02-13 08:18:48 +01002757 /* forced codec slots */
Ozan Çağlayan93574842009-05-23 15:00:04 +03002758 SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
Takashi Iwai20db7cb2009-02-13 08:18:48 +01002759 SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
Jaroslav Kyselaf3af9052012-04-26 17:52:35 +02002760 /* WinFast VP200 H (Teradici) user reported broken communication */
2761 SND_PCI_QUIRK(0x3a21, 0x040d, "WinFast VP200 H", 0x101),
Takashi Iwai669ba272007-08-17 09:17:36 +02002762 {}
2763};
2764
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01002765#define AZX_FORCE_CODEC_MASK 0x100
2766
Takashi Iwai5aba4f82008-01-07 15:16:37 +01002767static void __devinit check_probe_mask(struct azx *chip, int dev)
Takashi Iwai669ba272007-08-17 09:17:36 +02002768{
2769 const struct snd_pci_quirk *q;
2770
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01002771 chip->codec_probe_mask = probe_mask[dev];
2772 if (chip->codec_probe_mask == -1) {
Takashi Iwai669ba272007-08-17 09:17:36 +02002773 q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
2774 if (q) {
2775 printk(KERN_INFO
2776 "hda_intel: probe_mask set to 0x%x "
2777 "for device %04x:%04x\n",
2778 q->value, q->subvendor, q->subdevice);
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01002779 chip->codec_probe_mask = q->value;
Takashi Iwai669ba272007-08-17 09:17:36 +02002780 }
2781 }
Takashi Iwaif1eaaee2009-02-13 08:16:55 +01002782
2783 /* check forced option */
2784 if (chip->codec_probe_mask != -1 &&
2785 (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
2786 chip->codec_mask = chip->codec_probe_mask & 0xff;
2787 printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n",
2788 chip->codec_mask);
2789 }
Takashi Iwai669ba272007-08-17 09:17:36 +02002790}
2791
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002792/*
Takashi Iwai716238552009-09-28 13:14:04 +02002793 * white/black-list for enable_msi
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002794 */
Takashi Iwai716238552009-09-28 13:14:04 +02002795static struct snd_pci_quirk msi_black_list[] __devinitdata = {
Takashi Iwai9dc83982009-12-22 08:15:01 +01002796 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
Takashi Iwai0a27fcf2010-02-15 17:05:28 +01002797 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
Ralf Gerbigecd21622010-03-09 18:25:47 +01002798 SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
Michele Ballabio4193d132010-03-06 21:06:46 +01002799 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
Takashi Iwai38155952010-04-04 12:14:03 +02002800 SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002801 {}
2802};
2803
2804static void __devinit check_msi(struct azx *chip)
2805{
2806 const struct snd_pci_quirk *q;
2807
Takashi Iwai716238552009-09-28 13:14:04 +02002808 if (enable_msi >= 0) {
2809 chip->msi = !!enable_msi;
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002810 return;
Takashi Iwai716238552009-09-28 13:14:04 +02002811 }
2812 chip->msi = 1; /* enable MSI as default */
2813 q = snd_pci_quirk_lookup(chip->pci, msi_black_list);
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002814 if (q) {
2815 printk(KERN_INFO
2816 "hda_intel: msi for device %04x:%04x set to %d\n",
2817 q->subvendor, q->subdevice, q->value);
2818 chip->msi = q->value;
Takashi Iwai80c43ed2010-03-15 15:51:53 +01002819 return;
2820 }
2821
2822 /* NVidia chipsets seem to cause troubles with MSI */
Takashi Iwai9477c582011-05-25 09:11:37 +02002823 if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
2824 printk(KERN_INFO "hda_intel: Disabling MSI\n");
Takashi Iwai80c43ed2010-03-15 15:51:53 +01002825 chip->msi = 0;
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002826 }
2827}
2828
Takashi Iwaia1585d72011-12-14 09:27:04 +01002829/* check the snoop mode availability */
2830static void __devinit azx_check_snoop_available(struct azx *chip)
2831{
2832 bool snoop = chip->snoop;
2833
2834 switch (chip->driver_type) {
2835 case AZX_DRIVER_VIA:
2836 /* force to non-snoop mode for a new VIA controller
2837 * when BIOS is set
2838 */
2839 if (snoop) {
2840 u8 val;
2841 pci_read_config_byte(chip->pci, 0x42, &val);
2842 if (!(val & 0x80) && chip->pci->revision == 0x30)
2843 snoop = false;
2844 }
2845 break;
2846 case AZX_DRIVER_ATIHDMI_NS:
2847 /* new ATI HDMI requires non-snoop */
2848 snoop = false;
2849 break;
2850 }
2851
2852 if (snoop != chip->snoop) {
2853 snd_printk(KERN_INFO SFX "Force to %s mode\n",
2854 snoop ? "snoop" : "non-snoop");
2855 chip->snoop = snoop;
2856 }
2857}
Takashi Iwai669ba272007-08-17 09:17:36 +02002858
2859/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 * constructor
2861 */
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002862static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
Takashi Iwai9477c582011-05-25 09:11:37 +02002863 int dev, unsigned int driver_caps,
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002864 struct azx **rchip)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865{
Takashi Iwaia98f90f2005-11-17 14:59:02 +01002866 static struct snd_device_ops ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 .dev_free = azx_dev_free,
2868 };
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002869 struct azx *chip;
2870 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
2872 *rchip = NULL;
Tobin Davisbcd72002008-01-15 11:23:55 +01002873
Pavel Machek927fc862006-08-31 17:03:43 +02002874 err = pci_enable_device(pci);
2875 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 return err;
2877
Takashi Iwaie560d8d2005-09-09 14:21:46 +02002878 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
Pavel Machek927fc862006-08-31 17:03:43 +02002879 if (!chip) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
2881 pci_disable_device(pci);
2882 return -ENOMEM;
2883 }
2884
2885 spin_lock_init(&chip->reg_lock);
Ingo Molnar62932df2006-01-16 16:34:20 +01002886 mutex_init(&chip->open_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 chip->card = card;
2888 chip->pci = pci;
2889 chip->irq = -1;
Takashi Iwai9477c582011-05-25 09:11:37 +02002890 chip->driver_caps = driver_caps;
2891 chip->driver_type = driver_caps & 0xff;
Takashi Iwai4d8e22e2009-08-11 14:21:26 +02002892 check_msi(chip);
Takashi Iwai555e2192008-06-10 17:53:34 +02002893 chip->dev_index = dev;
Takashi Iwai9ad593f2008-05-16 12:34:47 +02002894 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
Takashi Iwai01b65bf2011-11-24 14:31:46 +01002895 INIT_LIST_HEAD(&chip->pcm_list);
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002896 init_vga_switcheroo(chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897
Shahin Ghazinouribeaffc32010-05-11 08:19:55 +02002898 chip->position_fix[0] = chip->position_fix[1] =
2899 check_position_fix(chip, position_fix[dev]);
Takashi Iwaia6f2fd52012-02-28 11:58:40 +01002900 /* combo mode uses LPIB for playback */
2901 if (chip->position_fix[0] == POS_FIX_COMBO) {
2902 chip->position_fix[0] = POS_FIX_LPIB;
2903 chip->position_fix[1] = POS_FIX_AUTO;
2904 }
2905
Takashi Iwai5aba4f82008-01-07 15:16:37 +01002906 check_probe_mask(chip, dev);
Takashi Iwai3372a152007-02-01 15:46:50 +01002907
Takashi Iwai27346162006-01-12 18:28:44 +01002908 chip->single_cmd = single_cmd;
Takashi Iwai27fe48d92011-09-28 17:16:09 +02002909 chip->snoop = hda_snoop;
Takashi Iwaia1585d72011-12-14 09:27:04 +01002910 azx_check_snoop_available(chip);
Takashi Iwaic74db862005-05-12 14:26:27 +02002911
Takashi Iwai5c0d7bc2008-06-10 17:53:35 +02002912 if (bdl_pos_adj[dev] < 0) {
2913 switch (chip->driver_type) {
Takashi Iwai0c6341a2008-06-13 20:50:27 +02002914 case AZX_DRIVER_ICH:
Seth Heasley32679f92010-02-22 17:31:09 -08002915 case AZX_DRIVER_PCH:
Takashi Iwai0c6341a2008-06-13 20:50:27 +02002916 bdl_pos_adj[dev] = 1;
Takashi Iwai5c0d7bc2008-06-10 17:53:35 +02002917 break;
2918 default:
Takashi Iwai0c6341a2008-06-13 20:50:27 +02002919 bdl_pos_adj[dev] = 32;
Takashi Iwai5c0d7bc2008-06-10 17:53:35 +02002920 break;
2921 }
2922 }
2923
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002924 if (check_hdmi_disabled(pci)) {
2925 snd_printk(KERN_INFO SFX "VGA controller for %s is disabled\n",
2926 pci_name(pci));
2927 if (use_vga_switcheroo(chip)) {
2928 snd_printk(KERN_INFO SFX "Delaying initialization\n");
2929 chip->disabled = true;
2930 goto ok;
2931 }
2932 kfree(chip);
2933 pci_disable_device(pci);
2934 return -ENXIO;
2935 }
2936
2937 err = azx_first_init(chip);
2938 if (err < 0) {
2939 azx_free(chip);
2940 return err;
2941 }
2942
2943 ok:
2944 err = register_vga_switcheroo(chip);
2945 if (err < 0) {
2946 snd_printk(KERN_ERR SFX
2947 "Error registering VGA-switcheroo client\n");
2948 azx_free(chip);
2949 return err;
2950 }
2951
2952 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2953 if (err < 0) {
2954 snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
2955 azx_free(chip);
2956 return err;
2957 }
2958
2959 *rchip = chip;
2960 return 0;
2961}
2962
2963static int DELAYED_INIT_MARK azx_first_init(struct azx *chip)
2964{
2965 int dev = chip->dev_index;
2966 struct pci_dev *pci = chip->pci;
2967 struct snd_card *card = chip->card;
2968 int i, err;
2969 unsigned short gcap;
2970
Takashi Iwai07e4ca52005-08-24 14:14:57 +02002971#if BITS_PER_LONG != 64
2972 /* Fix up base address on ULI M5461 */
2973 if (chip->driver_type == AZX_DRIVER_ULI) {
2974 u16 tmp3;
2975 pci_read_config_word(pci, 0x40, &tmp3);
2976 pci_write_config_word(pci, 0x40, tmp3 | 0x10);
2977 pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
2978 }
2979#endif
2980
Pavel Machek927fc862006-08-31 17:03:43 +02002981 err = pci_request_regions(pci, "ICH HD audio");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002982 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 return err;
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002984 chip->region_requested = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985
Pavel Machek927fc862006-08-31 17:03:43 +02002986 chip->addr = pci_resource_start(pci, 0);
Arjan van de Ven2f5ad542008-09-28 16:20:09 -07002987 chip->remap_addr = pci_ioremap_bar(pci, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 if (chip->remap_addr == NULL) {
2989 snd_printk(KERN_ERR SFX "ioremap error\n");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002990 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991 }
2992
Takashi Iwai68e7fff2006-10-23 13:40:59 +02002993 if (chip->msi)
2994 if (pci_enable_msi(pci) < 0)
2995 chip->msi = 0;
Stephen Hemminger7376d012006-08-21 19:17:46 +02002996
Takashi Iwaia82d51e2012-04-26 12:23:42 +02002997 if (azx_acquire_irq(chip, 0) < 0)
2998 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999
3000 pci_set_master(pci);
3001 synchronize_irq(chip->irq);
3002
Tobin Davisbcd72002008-01-15 11:23:55 +01003003 gcap = azx_readw(chip, GCAP);
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02003004 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
Tobin Davisbcd72002008-01-15 11:23:55 +01003005
Andiry Brienzadc4c2e62009-07-08 13:55:31 +08003006 /* disable SB600 64bit support for safety */
Takashi Iwai9477c582011-05-25 09:11:37 +02003007 if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
Andiry Brienzadc4c2e62009-07-08 13:55:31 +08003008 struct pci_dev *p_smbus;
3009 p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
3010 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
3011 NULL);
3012 if (p_smbus) {
3013 if (p_smbus->revision < 0x30)
3014 gcap &= ~ICH6_GCAP_64OK;
3015 pci_dev_put(p_smbus);
3016 }
3017 }
Takashi Iwai09240cf2009-03-17 07:47:18 +01003018
Takashi Iwai9477c582011-05-25 09:11:37 +02003019 /* disable 64bit DMA address on some devices */
3020 if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
3021 snd_printd(SFX "Disabling 64bit DMA\n");
Jaroslav Kysela396087e2009-12-09 10:44:47 +01003022 gcap &= ~ICH6_GCAP_64OK;
Takashi Iwai9477c582011-05-25 09:11:37 +02003023 }
Jaroslav Kysela396087e2009-12-09 10:44:47 +01003024
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003025 /* disable buffer size rounding to 128-byte multiples if supported */
Takashi Iwai7bfe0592012-01-23 17:53:39 +01003026 if (align_buffer_size >= 0)
3027 chip->align_buffer_size = !!align_buffer_size;
3028 else {
3029 if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
3030 chip->align_buffer_size = 0;
3031 else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
3032 chip->align_buffer_size = 1;
3033 else
3034 chip->align_buffer_size = 1;
3035 }
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003036
Takashi Iwaicf7aaca2008-02-06 15:05:57 +01003037 /* allow 64bit DMA address if supported by H/W */
Takashi Iwaib21fadb2009-05-28 12:26:15 +02003038 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
Yang Hongyange9304382009-04-13 14:40:14 -07003039 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
Takashi Iwai09240cf2009-03-17 07:47:18 +01003040 else {
Yang Hongyange9304382009-04-13 14:40:14 -07003041 pci_set_dma_mask(pci, DMA_BIT_MASK(32));
3042 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
Takashi Iwai09240cf2009-03-17 07:47:18 +01003043 }
Takashi Iwaicf7aaca2008-02-06 15:05:57 +01003044
Takashi Iwai8b6ed8e2008-02-19 11:36:35 +01003045 /* read number of streams from GCAP register instead of using
3046 * hardcoded value
3047 */
3048 chip->capture_streams = (gcap >> 8) & 0x0f;
3049 chip->playback_streams = (gcap >> 12) & 0x0f;
3050 if (!chip->playback_streams && !chip->capture_streams) {
Tobin Davisbcd72002008-01-15 11:23:55 +01003051 /* gcap didn't give any info, switching to old method */
3052
3053 switch (chip->driver_type) {
3054 case AZX_DRIVER_ULI:
3055 chip->playback_streams = ULI_NUM_PLAYBACK;
3056 chip->capture_streams = ULI_NUM_CAPTURE;
Tobin Davisbcd72002008-01-15 11:23:55 +01003057 break;
3058 case AZX_DRIVER_ATIHDMI:
Andiry Xu1815b342011-12-14 16:10:27 +08003059 case AZX_DRIVER_ATIHDMI_NS:
Tobin Davisbcd72002008-01-15 11:23:55 +01003060 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
3061 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
Tobin Davisbcd72002008-01-15 11:23:55 +01003062 break;
Yang, Libinc4da29c2008-11-13 11:07:07 +01003063 case AZX_DRIVER_GENERIC:
Tobin Davisbcd72002008-01-15 11:23:55 +01003064 default:
3065 chip->playback_streams = ICH6_NUM_PLAYBACK;
3066 chip->capture_streams = ICH6_NUM_CAPTURE;
Tobin Davisbcd72002008-01-15 11:23:55 +01003067 break;
3068 }
Takashi Iwai07e4ca52005-08-24 14:14:57 +02003069 }
Takashi Iwai8b6ed8e2008-02-19 11:36:35 +01003070 chip->capture_index_offset = 0;
3071 chip->playback_index_offset = chip->capture_streams;
Takashi Iwai07e4ca52005-08-24 14:14:57 +02003072 chip->num_streams = chip->playback_streams + chip->capture_streams;
Takashi Iwaid01ce992007-07-27 16:52:19 +02003073 chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
3074 GFP_KERNEL);
Pavel Machek927fc862006-08-31 17:03:43 +02003075 if (!chip->azx_dev) {
Takashi Iwai4abc1cc2009-05-19 12:16:46 +02003076 snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003077 return -ENOMEM;
Takashi Iwai07e4ca52005-08-24 14:14:57 +02003078 }
3079
Takashi Iwai4ce107b2008-02-06 14:50:19 +01003080 for (i = 0; i < chip->num_streams; i++) {
3081 /* allocate memory for the BDL for each stream */
3082 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
3083 snd_dma_pci_data(chip->pci),
3084 BDL_SIZE, &chip->azx_dev[i].bdl);
3085 if (err < 0) {
3086 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003087 return -ENOMEM;
Takashi Iwai4ce107b2008-02-06 14:50:19 +01003088 }
Takashi Iwai27fe48d92011-09-28 17:16:09 +02003089 mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 }
Takashi Iwai0be3b5d2005-09-05 17:11:40 +02003091 /* allocate memory for the position buffer */
Takashi Iwaid01ce992007-07-27 16:52:19 +02003092 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
3093 snd_dma_pci_data(chip->pci),
3094 chip->num_streams * 8, &chip->posbuf);
3095 if (err < 0) {
Takashi Iwai0be3b5d2005-09-05 17:11:40 +02003096 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003097 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 }
Takashi Iwai27fe48d92011-09-28 17:16:09 +02003099 mark_pages_wc(chip, &chip->posbuf, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100 /* allocate CORB/RIRB */
Takashi Iwai81740862009-05-26 15:22:00 +02003101 err = azx_alloc_cmd_io(chip);
3102 if (err < 0)
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003103 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104
3105 /* initialize streams */
3106 azx_init_stream(chip);
3107
3108 /* initialize chip */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003109 azx_init_pci(chip);
Jaroslav Kysela10e77dd2010-03-26 11:04:38 +01003110 azx_init_chip(chip, (probe_only[dev] & 2) == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111
3112 /* codec detection */
Pavel Machek927fc862006-08-31 17:03:43 +02003113 if (!chip->codec_mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 snd_printk(KERN_ERR SFX "no codecs found!\n");
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003115 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 }
3117
Takashi Iwai07e4ca52005-08-24 14:14:57 +02003118 strcpy(card->driver, "HDA-Intel");
Takashi Iwai18cb7102009-04-16 10:22:24 +02003119 strlcpy(card->shortname, driver_short_names[chip->driver_type],
3120 sizeof(card->shortname));
3121 snprintf(card->longname, sizeof(card->longname),
3122 "%s at 0x%lx irq %i",
3123 card->shortname, chip->addr, chip->irq);
Takashi Iwai07e4ca52005-08-24 14:14:57 +02003124
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126}
3127
Takashi Iwaicb53c622007-08-10 17:21:45 +02003128static void power_down_all_codecs(struct azx *chip)
3129{
3130#ifdef CONFIG_SND_HDA_POWER_SAVE
3131 /* The codecs were powered up in snd_hda_codec_new().
3132 * Now all initialization done, so turn them down if possible
3133 */
3134 struct hda_codec *codec;
3135 list_for_each_entry(codec, &chip->bus->codec_list, list) {
3136 snd_hda_power_down(codec);
3137 }
3138#endif
3139}
3140
Takashi Iwaid01ce992007-07-27 16:52:19 +02003141static int __devinit azx_probe(struct pci_dev *pci,
3142 const struct pci_device_id *pci_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143{
Takashi Iwai5aba4f82008-01-07 15:16:37 +01003144 static int dev;
Takashi Iwaia98f90f2005-11-17 14:59:02 +01003145 struct snd_card *card;
3146 struct azx *chip;
Pavel Machek927fc862006-08-31 17:03:43 +02003147 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148
Takashi Iwai5aba4f82008-01-07 15:16:37 +01003149 if (dev >= SNDRV_CARDS)
3150 return -ENODEV;
3151 if (!enable[dev]) {
3152 dev++;
3153 return -ENOENT;
3154 }
3155
Takashi Iwaie58de7b2008-12-28 16:44:30 +01003156 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
3157 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 snd_printk(KERN_ERR SFX "Error creating card!\n");
Takashi Iwaie58de7b2008-12-28 16:44:30 +01003159 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 }
3161
Takashi Iwai4ea6fbc2009-06-17 09:52:54 +02003162 /* set this here since it's referred in snd_hda_load_patch() */
3163 snd_card_set_dev(card, &pci->dev);
3164
Takashi Iwai5aba4f82008-01-07 15:16:37 +01003165 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003166 if (err < 0)
3167 goto out_free;
Takashi Iwai421a1252005-11-17 16:11:09 +01003168 card->private_data = chip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003170 if (!chip->disabled) {
3171 err = azx_probe_continue(chip);
3172 if (err < 0)
3173 goto out_free;
3174 }
3175
3176 pci_set_drvdata(pci, card);
3177
3178 dev++;
3179 return 0;
3180
3181out_free:
3182 snd_card_free(card);
3183 return err;
3184}
3185
3186static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
3187{
3188 int dev = chip->dev_index;
3189 int err;
3190
Jaroslav Kysela2dca0bb2009-11-13 18:41:52 +01003191#ifdef CONFIG_SND_HDA_INPUT_BEEP
3192 chip->beep_mode = beep_mode[dev];
3193#endif
3194
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195 /* create codec instances */
Takashi Iwaia1e21c92009-06-17 09:33:52 +02003196 err = azx_codec_create(chip, model[dev]);
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003197 if (err < 0)
3198 goto out_free;
Takashi Iwai4ea6fbc2009-06-17 09:52:54 +02003199#ifdef CONFIG_SND_HDA_PATCH_LOADER
Takashi Iwai41a63f12011-02-10 17:39:20 +01003200 if (patch[dev] && *patch[dev]) {
Takashi Iwai4ea6fbc2009-06-17 09:52:54 +02003201 snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
3202 patch[dev]);
3203 err = snd_hda_load_patch(chip->bus, patch[dev]);
3204 if (err < 0)
3205 goto out_free;
3206 }
3207#endif
Jaroslav Kysela10e77dd2010-03-26 11:04:38 +01003208 if ((probe_only[dev] & 1) == 0) {
Takashi Iwaia1e21c92009-06-17 09:33:52 +02003209 err = azx_codec_configure(chip);
3210 if (err < 0)
3211 goto out_free;
3212 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213
3214 /* create PCM streams */
Takashi Iwai176d5332008-07-30 15:01:44 +02003215 err = snd_hda_build_pcms(chip->bus);
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003216 if (err < 0)
3217 goto out_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218
3219 /* create mixer controls */
Takashi Iwaid01ce992007-07-27 16:52:19 +02003220 err = azx_mixer_create(chip);
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003221 if (err < 0)
3222 goto out_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003224 err = snd_card_register(chip->card);
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003225 if (err < 0)
3226 goto out_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227
Takashi Iwaicb53c622007-08-10 17:21:45 +02003228 chip->running = 1;
3229 power_down_all_codecs(chip);
Takashi Iwai0cbf0092008-10-29 16:18:25 +01003230 azx_notifier_register(chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231
Takashi Iwai91219472012-04-26 12:13:25 +02003232 return 0;
3233
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003234out_free:
Takashi Iwaia82d51e2012-04-26 12:23:42 +02003235 chip->init_failed = 1;
Wu Fengguang41dda0f2008-11-20 09:24:52 +08003236 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237}
3238
3239static void __devexit azx_remove(struct pci_dev *pci)
3240{
Takashi Iwai91219472012-04-26 12:13:25 +02003241 struct snd_card *card = pci_get_drvdata(pci);
3242 if (card)
3243 snd_card_free(card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 pci_set_drvdata(pci, NULL);
3245}
3246
3247/* PCI IDs */
Alexey Dobriyancebe41d2010-02-06 00:21:03 +02003248static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
Seth Heasleyd2f2fcd2010-01-12 17:03:35 -08003249 /* CPT */
Takashi Iwai9477c582011-05-25 09:11:37 +02003250 { PCI_DEVICE(0x8086, 0x1c20),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003251 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
Seth Heasleyc20c5a82012-06-14 14:23:53 -07003252 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
Seth Heasleycea310e2010-09-10 16:29:56 -07003253 /* PBG */
Takashi Iwai9477c582011-05-25 09:11:37 +02003254 { PCI_DEVICE(0x8086, 0x1d20),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003255 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3256 AZX_DCAPS_BUFSIZE},
Seth Heasleyd2edeb72011-04-20 10:59:57 -07003257 /* Panther Point */
Takashi Iwai9477c582011-05-25 09:11:37 +02003258 { PCI_DEVICE(0x8086, 0x1e20),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003259 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
Seth Heasleyc20c5a82012-06-14 14:23:53 -07003260 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
Seth Heasley8bc039a2012-01-23 16:24:31 -08003261 /* Lynx Point */
3262 { PCI_DEVICE(0x8086, 0x8c20),
3263 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
Seth Heasleyc20c5a82012-06-14 14:23:53 -07003264 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
Wang Xingchaoe926f2c2012-06-13 10:23:51 +08003265 /* Haswell */
3266 { PCI_DEVICE(0x8086, 0x0c0c),
Takashi Iwaibdbe34d2012-07-16 16:17:10 +02003267 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
Wang Xingchaoe926f2c2012-06-13 10:23:51 +08003268 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
Takashi Iwai87218e92008-02-21 08:13:11 +01003269 /* SCH */
Takashi Iwai9477c582011-05-25 09:11:37 +02003270 { PCI_DEVICE(0x8086, 0x811b),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003271 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
David Henningsson645e9032011-12-14 15:52:30 +08003272 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */
Li Peng09904b92011-12-28 15:17:26 +00003273 { PCI_DEVICE(0x8086, 0x080a),
3274 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
David Henningsson716e5db2012-01-04 10:12:54 +01003275 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */
David Henningsson645e9032011-12-14 15:52:30 +08003276 /* ICH */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003277 { PCI_DEVICE(0x8086, 0x2668),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003278 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3279 AZX_DCAPS_BUFSIZE }, /* ICH6 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003280 { PCI_DEVICE(0x8086, 0x27d8),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003281 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3282 AZX_DCAPS_BUFSIZE }, /* ICH7 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003283 { PCI_DEVICE(0x8086, 0x269a),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003284 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3285 AZX_DCAPS_BUFSIZE }, /* ESB2 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003286 { PCI_DEVICE(0x8086, 0x284b),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003287 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3288 AZX_DCAPS_BUFSIZE }, /* ICH8 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003289 { PCI_DEVICE(0x8086, 0x293e),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003290 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3291 AZX_DCAPS_BUFSIZE }, /* ICH9 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003292 { PCI_DEVICE(0x8086, 0x293f),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003293 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3294 AZX_DCAPS_BUFSIZE }, /* ICH9 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003295 { PCI_DEVICE(0x8086, 0x3a3e),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003296 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3297 AZX_DCAPS_BUFSIZE }, /* ICH10 */
Takashi Iwai8b0bd222011-06-10 14:56:26 +02003298 { PCI_DEVICE(0x8086, 0x3a6e),
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003299 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
3300 AZX_DCAPS_BUFSIZE }, /* ICH10 */
Takashi Iwaib6864532010-09-15 10:17:26 +02003301 /* Generic Intel */
3302 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
3303 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3304 .class_mask = 0xffffff,
Pierre-Louis Bossart2ae66c22011-08-04 10:12:56 -05003305 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
Takashi Iwai9477c582011-05-25 09:11:37 +02003306 /* ATI SB 450/600/700/800/900 */
3307 { PCI_DEVICE(0x1002, 0x437b),
3308 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
3309 { PCI_DEVICE(0x1002, 0x4383),
3310 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
3311 /* AMD Hudson */
3312 { PCI_DEVICE(0x1022, 0x780d),
3313 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
Takashi Iwai87218e92008-02-21 08:13:11 +01003314 /* ATI HDMI */
Takashi Iwai9477c582011-05-25 09:11:37 +02003315 { PCI_DEVICE(0x1002, 0x793b),
3316 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3317 { PCI_DEVICE(0x1002, 0x7919),
3318 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3319 { PCI_DEVICE(0x1002, 0x960f),
3320 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3321 { PCI_DEVICE(0x1002, 0x970f),
3322 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3323 { PCI_DEVICE(0x1002, 0xaa00),
3324 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3325 { PCI_DEVICE(0x1002, 0xaa08),
3326 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3327 { PCI_DEVICE(0x1002, 0xaa10),
3328 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3329 { PCI_DEVICE(0x1002, 0xaa18),
3330 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3331 { PCI_DEVICE(0x1002, 0xaa20),
3332 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3333 { PCI_DEVICE(0x1002, 0xaa28),
3334 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3335 { PCI_DEVICE(0x1002, 0xaa30),
3336 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3337 { PCI_DEVICE(0x1002, 0xaa38),
3338 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3339 { PCI_DEVICE(0x1002, 0xaa40),
3340 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
3341 { PCI_DEVICE(0x1002, 0xaa48),
3342 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
Andiry Xu1815b342011-12-14 16:10:27 +08003343 { PCI_DEVICE(0x1002, 0x9902),
3344 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
3345 { PCI_DEVICE(0x1002, 0xaaa0),
3346 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
3347 { PCI_DEVICE(0x1002, 0xaaa8),
3348 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
3349 { PCI_DEVICE(0x1002, 0xaab0),
3350 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI },
Takashi Iwai87218e92008-02-21 08:13:11 +01003351 /* VIA VT8251/VT8237A */
Takashi Iwai9477c582011-05-25 09:11:37 +02003352 { PCI_DEVICE(0x1106, 0x3288),
3353 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
Annie Liu754fdff2012-06-08 19:18:39 +08003354 /* VIA GFX VT7122/VX900 */
3355 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
3356 /* VIA GFX VT6122/VX11 */
3357 { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
Takashi Iwai87218e92008-02-21 08:13:11 +01003358 /* SIS966 */
3359 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
3360 /* ULI M5461 */
3361 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
3362 /* NVIDIA MCP */
Takashi Iwai0c2fd1bf42009-12-18 16:41:39 +01003363 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
3364 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3365 .class_mask = 0xffffff,
Takashi Iwai9477c582011-05-25 09:11:37 +02003366 .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
Kailang Yangf2690022008-05-27 11:44:55 +02003367 /* Teradici */
Takashi Iwai9477c582011-05-25 09:11:37 +02003368 { PCI_DEVICE(0x6549, 0x1200),
3369 .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
Takashi Iwai4e01f542009-04-16 08:53:34 +02003370 /* Creative X-Fi (CA0110-IBG) */
Takashi Iwaif2a8eca2012-06-11 15:51:54 +02003371 /* CTHDA chips */
3372 { PCI_DEVICE(0x1102, 0x0010),
3373 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
3374 { PCI_DEVICE(0x1102, 0x0012),
3375 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
Takashi Iwai313f6e22009-05-18 12:40:52 +02003376#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
3377 /* the following entry conflicts with snd-ctxfi driver,
3378 * as ctxfi driver mutates from HD-audio to native mode with
3379 * a special command sequence.
3380 */
Takashi Iwai4e01f542009-04-16 08:53:34 +02003381 { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
3382 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3383 .class_mask = 0xffffff,
Takashi Iwai9477c582011-05-25 09:11:37 +02003384 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
Takashi Iwai69f9ba92011-11-06 13:49:13 +01003385 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
Takashi Iwai313f6e22009-05-18 12:40:52 +02003386#else
3387 /* this entry seems still valid -- i.e. without emu20kx chip */
Takashi Iwai9477c582011-05-25 09:11:37 +02003388 { PCI_DEVICE(0x1102, 0x0009),
3389 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
Takashi Iwai69f9ba92011-11-06 13:49:13 +01003390 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
Takashi Iwai313f6e22009-05-18 12:40:52 +02003391#endif
Otavio Salvadore35d4b12010-09-26 23:35:06 -03003392 /* Vortex86MX */
3393 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
Bankim Bhavsar0f0714c52011-01-17 15:23:21 +01003394 /* VMware HDAudio */
3395 { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
Andiry Brienza9176b672009-07-17 11:32:32 +08003396 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
Yang, Libinc4da29c2008-11-13 11:07:07 +01003397 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
3398 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3399 .class_mask = 0xffffff,
Takashi Iwai9477c582011-05-25 09:11:37 +02003400 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
Andiry Brienza9176b672009-07-17 11:32:32 +08003401 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
3402 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
3403 .class_mask = 0xffffff,
Takashi Iwai9477c582011-05-25 09:11:37 +02003404 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
Linus Torvalds1da177e2005-04-16 15:20:36 -07003405 { 0, }
3406};
3407MODULE_DEVICE_TABLE(pci, azx_ids);
3408
3409/* pci_driver definition */
Takashi Iwaie9f66d92012-04-24 12:25:00 +02003410static struct pci_driver azx_driver = {
Takashi Iwai3733e422011-06-10 16:20:20 +02003411 .name = KBUILD_MODNAME,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 .id_table = azx_ids,
3413 .probe = azx_probe,
3414 .remove = __devexit_p(azx_remove),
Takashi Iwai421a1252005-11-17 16:11:09 +01003415#ifdef CONFIG_PM
3416 .suspend = azx_suspend,
3417 .resume = azx_resume,
3418#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419};
3420
Takashi Iwaie9f66d92012-04-24 12:25:00 +02003421module_pci_driver(azx_driver);