diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-04-27 06:25:42 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-04-27 06:25:42 -0400 |
commit | 8ab418d3651b14d38498d868617a7280ccc6de08 (patch) | |
tree | f416b17d14ef9a7bd1bfdacea2f1b56ab948b14f /include/sound | |
parent | 782e50e0b38ff284dead13265f1c3e04004e507d (diff) | |
parent | 0dd76f36efa43fa75a568b0d24736a9e51d51170 (diff) |
Merge branch 'topic/hda' into for-4.2
Diffstat (limited to 'include/sound')
-rw-r--r-- | include/sound/hda_register.h | 152 | ||||
-rw-r--r-- | include/sound/hdaudio.h | 286 |
2 files changed, 435 insertions, 3 deletions
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h new file mode 100644 index 000000000000..4f6d3fce6ee6 --- /dev/null +++ b/include/sound/hda_register.h | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * HD-audio controller (Azalia) registers and helpers | ||
3 | * | ||
4 | * For traditional reasons, we still use azx_ prefix here | ||
5 | */ | ||
6 | |||
7 | #ifndef __SOUND_HDA_REGISTER_H | ||
8 | #define __SOUND_HDA_REGISTER_H | ||
9 | |||
10 | #include <linux/io.h> | ||
11 | #include <sound/hdaudio.h> | ||
12 | |||
13 | #define AZX_REG_GCAP 0x00 | ||
14 | #define AZX_GCAP_64OK (1 << 0) /* 64bit address support */ | ||
15 | #define AZX_GCAP_NSDO (3 << 1) /* # of serial data out signals */ | ||
16 | #define AZX_GCAP_BSS (31 << 3) /* # of bidirectional streams */ | ||
17 | #define AZX_GCAP_ISS (15 << 8) /* # of input streams */ | ||
18 | #define AZX_GCAP_OSS (15 << 12) /* # of output streams */ | ||
19 | #define AZX_REG_VMIN 0x02 | ||
20 | #define AZX_REG_VMAJ 0x03 | ||
21 | #define AZX_REG_OUTPAY 0x04 | ||
22 | #define AZX_REG_INPAY 0x06 | ||
23 | #define AZX_REG_GCTL 0x08 | ||
24 | #define AZX_GCTL_RESET (1 << 0) /* controller reset */ | ||
25 | #define AZX_GCTL_FCNTRL (1 << 1) /* flush control */ | ||
26 | #define AZX_GCTL_UNSOL (1 << 8) /* accept unsol. response enable */ | ||
27 | #define AZX_REG_WAKEEN 0x0c | ||
28 | #define AZX_REG_STATESTS 0x0e | ||
29 | #define AZX_REG_GSTS 0x10 | ||
30 | #define AZX_GSTS_FSTS (1 << 1) /* flush status */ | ||
31 | #define AZX_REG_INTCTL 0x20 | ||
32 | #define AZX_REG_INTSTS 0x24 | ||
33 | #define AZX_REG_WALLCLK 0x30 /* 24Mhz source */ | ||
34 | #define AZX_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */ | ||
35 | #define AZX_REG_SSYNC 0x38 | ||
36 | #define AZX_REG_CORBLBASE 0x40 | ||
37 | #define AZX_REG_CORBUBASE 0x44 | ||
38 | #define AZX_REG_CORBWP 0x48 | ||
39 | #define AZX_REG_CORBRP 0x4a | ||
40 | #define AZX_CORBRP_RST (1 << 15) /* read pointer reset */ | ||
41 | #define AZX_REG_CORBCTL 0x4c | ||
42 | #define AZX_CORBCTL_RUN (1 << 1) /* enable DMA */ | ||
43 | #define AZX_CORBCTL_CMEIE (1 << 0) /* enable memory error irq */ | ||
44 | #define AZX_REG_CORBSTS 0x4d | ||
45 | #define AZX_CORBSTS_CMEI (1 << 0) /* memory error indication */ | ||
46 | #define AZX_REG_CORBSIZE 0x4e | ||
47 | |||
48 | #define AZX_REG_RIRBLBASE 0x50 | ||
49 | #define AZX_REG_RIRBUBASE 0x54 | ||
50 | #define AZX_REG_RIRBWP 0x58 | ||
51 | #define AZX_RIRBWP_RST (1 << 15) /* write pointer reset */ | ||
52 | #define AZX_REG_RINTCNT 0x5a | ||
53 | #define AZX_REG_RIRBCTL 0x5c | ||
54 | #define AZX_RBCTL_IRQ_EN (1 << 0) /* enable IRQ */ | ||
55 | #define AZX_RBCTL_DMA_EN (1 << 1) /* enable DMA */ | ||
56 | #define AZX_RBCTL_OVERRUN_EN (1 << 2) /* enable overrun irq */ | ||
57 | #define AZX_REG_RIRBSTS 0x5d | ||
58 | #define AZX_RBSTS_IRQ (1 << 0) /* response irq */ | ||
59 | #define AZX_RBSTS_OVERRUN (1 << 2) /* overrun irq */ | ||
60 | #define AZX_REG_RIRBSIZE 0x5e | ||
61 | |||
62 | #define AZX_REG_IC 0x60 | ||
63 | #define AZX_REG_IR 0x64 | ||
64 | #define AZX_REG_IRS 0x68 | ||
65 | #define AZX_IRS_VALID (1<<1) | ||
66 | #define AZX_IRS_BUSY (1<<0) | ||
67 | |||
68 | #define AZX_REG_DPLBASE 0x70 | ||
69 | #define AZX_REG_DPUBASE 0x74 | ||
70 | #define AZX_DPLBASE_ENABLE 0x1 /* Enable position buffer */ | ||
71 | |||
72 | /* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ | ||
73 | enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | ||
74 | |||
75 | /* stream register offsets from stream base */ | ||
76 | #define AZX_REG_SD_CTL 0x00 | ||
77 | #define AZX_REG_SD_STS 0x03 | ||
78 | #define AZX_REG_SD_LPIB 0x04 | ||
79 | #define AZX_REG_SD_CBL 0x08 | ||
80 | #define AZX_REG_SD_LVI 0x0c | ||
81 | #define AZX_REG_SD_FIFOW 0x0e | ||
82 | #define AZX_REG_SD_FIFOSIZE 0x10 | ||
83 | #define AZX_REG_SD_FORMAT 0x12 | ||
84 | #define AZX_REG_SD_BDLPL 0x18 | ||
85 | #define AZX_REG_SD_BDLPU 0x1c | ||
86 | |||
87 | /* PCI space */ | ||
88 | #define AZX_PCIREG_TCSEL 0x44 | ||
89 | |||
90 | /* | ||
91 | * other constants | ||
92 | */ | ||
93 | |||
94 | /* max number of fragments - we may use more if allocating more pages for BDL */ | ||
95 | #define BDL_SIZE 4096 | ||
96 | #define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16) | ||
97 | #define AZX_MAX_FRAG 32 | ||
98 | /* max buffer size - no h/w limit, you can increase as you like */ | ||
99 | #define AZX_MAX_BUF_SIZE (1024*1024*1024) | ||
100 | |||
101 | /* RIRB int mask: overrun[2], response[0] */ | ||
102 | #define RIRB_INT_RESPONSE 0x01 | ||
103 | #define RIRB_INT_OVERRUN 0x04 | ||
104 | #define RIRB_INT_MASK 0x05 | ||
105 | |||
106 | /* STATESTS int mask: S3,SD2,SD1,SD0 */ | ||
107 | #define STATESTS_INT_MASK ((1 << HDA_MAX_CODECS) - 1) | ||
108 | |||
109 | /* SD_CTL bits */ | ||
110 | #define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ | ||
111 | #define SD_CTL_DMA_START 0x02 /* stream DMA start bit */ | ||
112 | #define SD_CTL_STRIPE (3 << 16) /* stripe control */ | ||
113 | #define SD_CTL_TRAFFIC_PRIO (1 << 18) /* traffic priority */ | ||
114 | #define SD_CTL_DIR (1 << 19) /* bi-directional stream */ | ||
115 | #define SD_CTL_STREAM_TAG_MASK (0xf << 20) | ||
116 | #define SD_CTL_STREAM_TAG_SHIFT 20 | ||
117 | |||
118 | /* SD_CTL and SD_STS */ | ||
119 | #define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */ | ||
120 | #define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */ | ||
121 | #define SD_INT_COMPLETE 0x04 /* completion interrupt */ | ||
122 | #define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\ | ||
123 | SD_INT_COMPLETE) | ||
124 | |||
125 | /* SD_STS */ | ||
126 | #define SD_STS_FIFO_READY 0x20 /* FIFO ready */ | ||
127 | |||
128 | /* INTCTL and INTSTS */ | ||
129 | #define AZX_INT_ALL_STREAM 0xff /* all stream interrupts */ | ||
130 | #define AZX_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ | ||
131 | #define AZX_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ | ||
132 | |||
133 | /* below are so far hardcoded - should read registers in future */ | ||
134 | #define AZX_MAX_CORB_ENTRIES 256 | ||
135 | #define AZX_MAX_RIRB_ENTRIES 256 | ||
136 | |||
137 | /* | ||
138 | * helpers to read the stream position | ||
139 | */ | ||
140 | static inline unsigned int | ||
141 | snd_hdac_stream_get_pos_lpib(struct hdac_stream *stream) | ||
142 | { | ||
143 | return snd_hdac_stream_readl(stream, SD_LPIB); | ||
144 | } | ||
145 | |||
146 | static inline unsigned int | ||
147 | snd_hdac_stream_get_pos_posbuf(struct hdac_stream *stream) | ||
148 | { | ||
149 | return le32_to_cpu(*stream->posbuf); | ||
150 | } | ||
151 | |||
152 | #endif /* __SOUND_HDA_REGISTER_H */ | ||
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 2a8aa9dfb83d..6a2e030c836c 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h | |||
@@ -6,12 +6,17 @@ | |||
6 | #define __SOUND_HDAUDIO_H | 6 | #define __SOUND_HDAUDIO_H |
7 | 7 | ||
8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/timecounter.h> | ||
11 | #include <sound/core.h> | ||
12 | #include <sound/memalloc.h> | ||
9 | #include <sound/hda_verbs.h> | 13 | #include <sound/hda_verbs.h> |
10 | 14 | ||
11 | /* codec node id */ | 15 | /* codec node id */ |
12 | typedef u16 hda_nid_t; | 16 | typedef u16 hda_nid_t; |
13 | 17 | ||
14 | struct hdac_bus; | 18 | struct hdac_bus; |
19 | struct hdac_stream; | ||
15 | struct hdac_device; | 20 | struct hdac_device; |
16 | struct hdac_driver; | 21 | struct hdac_driver; |
17 | struct hdac_widget_tree; | 22 | struct hdac_widget_tree; |
@@ -85,6 +90,7 @@ struct hdac_device { | |||
85 | enum { | 90 | enum { |
86 | HDA_DEV_CORE, | 91 | HDA_DEV_CORE, |
87 | HDA_DEV_LEGACY, | 92 | HDA_DEV_LEGACY, |
93 | HDA_DEV_ASOC, | ||
88 | }; | 94 | }; |
89 | 95 | ||
90 | /* direction */ | 96 | /* direction */ |
@@ -118,6 +124,15 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid, | |||
118 | hda_nid_t *conn_list, int max_conns); | 124 | hda_nid_t *conn_list, int max_conns); |
119 | int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid, | 125 | int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid, |
120 | hda_nid_t *start_id); | 126 | hda_nid_t *start_id); |
127 | unsigned int snd_hdac_calc_stream_format(unsigned int rate, | ||
128 | unsigned int channels, | ||
129 | unsigned int format, | ||
130 | unsigned int maxbps, | ||
131 | unsigned short spdif_ctls); | ||
132 | int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid, | ||
133 | u32 *ratesp, u64 *formatsp, unsigned int *bpsp); | ||
134 | bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid, | ||
135 | unsigned int format); | ||
121 | 136 | ||
122 | /** | 137 | /** |
123 | * snd_hdac_read_parm - read a codec parameter | 138 | * snd_hdac_read_parm - read a codec parameter |
@@ -161,7 +176,7 @@ struct hdac_driver { | |||
161 | #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver) | 176 | #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver) |
162 | 177 | ||
163 | /* | 178 | /* |
164 | * HD-audio bus base driver | 179 | * Bus verb operators |
165 | */ | 180 | */ |
166 | struct hdac_bus_ops { | 181 | struct hdac_bus_ops { |
167 | /* send a single command */ | 182 | /* send a single command */ |
@@ -171,11 +186,55 @@ struct hdac_bus_ops { | |||
171 | unsigned int *res); | 186 | unsigned int *res); |
172 | }; | 187 | }; |
173 | 188 | ||
189 | /* | ||
190 | * Lowlevel I/O operators | ||
191 | */ | ||
192 | struct hdac_io_ops { | ||
193 | /* mapped register accesses */ | ||
194 | void (*reg_writel)(u32 value, u32 __iomem *addr); | ||
195 | u32 (*reg_readl)(u32 __iomem *addr); | ||
196 | void (*reg_writew)(u16 value, u16 __iomem *addr); | ||
197 | u16 (*reg_readw)(u16 __iomem *addr); | ||
198 | void (*reg_writeb)(u8 value, u8 __iomem *addr); | ||
199 | u8 (*reg_readb)(u8 __iomem *addr); | ||
200 | /* Allocation ops */ | ||
201 | int (*dma_alloc_pages)(struct hdac_bus *bus, int type, size_t size, | ||
202 | struct snd_dma_buffer *buf); | ||
203 | void (*dma_free_pages)(struct hdac_bus *bus, | ||
204 | struct snd_dma_buffer *buf); | ||
205 | }; | ||
206 | |||
174 | #define HDA_UNSOL_QUEUE_SIZE 64 | 207 | #define HDA_UNSOL_QUEUE_SIZE 64 |
208 | #define HDA_MAX_CODECS 8 /* limit by controller side */ | ||
209 | |||
210 | /* HD Audio class code */ | ||
211 | #define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 | ||
175 | 212 | ||
213 | /* | ||
214 | * CORB/RIRB | ||
215 | * | ||
216 | * Each CORB entry is 4byte, RIRB is 8byte | ||
217 | */ | ||
218 | struct hdac_rb { | ||
219 | __le32 *buf; /* virtual address of CORB/RIRB buffer */ | ||
220 | dma_addr_t addr; /* physical address of CORB/RIRB buffer */ | ||
221 | unsigned short rp, wp; /* RIRB read/write pointers */ | ||
222 | int cmds[HDA_MAX_CODECS]; /* number of pending requests */ | ||
223 | u32 res[HDA_MAX_CODECS]; /* last read value */ | ||
224 | }; | ||
225 | |||
226 | /* | ||
227 | * HD-audio bus base driver | ||
228 | */ | ||
176 | struct hdac_bus { | 229 | struct hdac_bus { |
177 | struct device *dev; | 230 | struct device *dev; |
178 | const struct hdac_bus_ops *ops; | 231 | const struct hdac_bus_ops *ops; |
232 | const struct hdac_io_ops *io_ops; | ||
233 | |||
234 | /* h/w resources */ | ||
235 | unsigned long addr; | ||
236 | void __iomem *remap_addr; | ||
237 | int irq; | ||
179 | 238 | ||
180 | /* codec linked list */ | 239 | /* codec linked list */ |
181 | struct list_head codec_list; | 240 | struct list_head codec_list; |
@@ -189,18 +248,45 @@ struct hdac_bus { | |||
189 | unsigned int unsol_rp, unsol_wp; | 248 | unsigned int unsol_rp, unsol_wp; |
190 | struct work_struct unsol_work; | 249 | struct work_struct unsol_work; |
191 | 250 | ||
251 | /* bit flags of detected codecs */ | ||
252 | unsigned long codec_mask; | ||
253 | |||
192 | /* bit flags of powered codecs */ | 254 | /* bit flags of powered codecs */ |
193 | unsigned long codec_powered; | 255 | unsigned long codec_powered; |
194 | 256 | ||
195 | /* flags */ | 257 | /* CORB/RIRB */ |
258 | struct hdac_rb corb; | ||
259 | struct hdac_rb rirb; | ||
260 | unsigned int last_cmd[HDA_MAX_CODECS]; /* last sent command */ | ||
261 | |||
262 | /* CORB/RIRB and position buffers */ | ||
263 | struct snd_dma_buffer rb; | ||
264 | struct snd_dma_buffer posbuf; | ||
265 | |||
266 | /* hdac_stream linked list */ | ||
267 | struct list_head stream_list; | ||
268 | |||
269 | /* operation state */ | ||
270 | bool chip_init:1; /* h/w initialized */ | ||
271 | |||
272 | /* behavior flags */ | ||
196 | bool sync_write:1; /* sync after verb write */ | 273 | bool sync_write:1; /* sync after verb write */ |
274 | bool use_posbuf:1; /* use position buffer */ | ||
275 | bool snoop:1; /* enable snooping */ | ||
276 | bool align_bdle_4k:1; /* BDLE align 4K boundary */ | ||
277 | bool reverse_assign:1; /* assign devices in reverse order */ | ||
278 | bool corbrp_self_clear:1; /* CORBRP clears itself after reset */ | ||
279 | |||
280 | int bdl_pos_adj; /* BDL position adjustment */ | ||
197 | 281 | ||
198 | /* locks */ | 282 | /* locks */ |
283 | spinlock_t reg_lock; | ||
199 | struct mutex cmd_mutex; | 284 | struct mutex cmd_mutex; |
200 | }; | 285 | }; |
201 | 286 | ||
202 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, | 287 | int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, |
203 | const struct hdac_bus_ops *ops); | 288 | const struct hdac_bus_ops *ops, |
289 | const struct hdac_io_ops *io_ops); | ||
204 | void snd_hdac_bus_exit(struct hdac_bus *bus); | 290 | void snd_hdac_bus_exit(struct hdac_bus *bus); |
205 | int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, | 291 | int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr, |
206 | unsigned int cmd, unsigned int *res); | 292 | unsigned int cmd, unsigned int *res); |
@@ -222,6 +308,200 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec) | |||
222 | clear_bit(codec->addr, &codec->bus->codec_powered); | 308 | clear_bit(codec->addr, &codec->bus->codec_powered); |
223 | } | 309 | } |
224 | 310 | ||
311 | int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); | ||
312 | int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, | ||
313 | unsigned int *res); | ||
314 | |||
315 | bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); | ||
316 | void snd_hdac_bus_stop_chip(struct hdac_bus *bus); | ||
317 | void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus); | ||
318 | void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus); | ||
319 | void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus); | ||
320 | void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus); | ||
321 | |||
322 | void snd_hdac_bus_update_rirb(struct hdac_bus *bus); | ||
323 | void snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status, | ||
324 | void (*ack)(struct hdac_bus *, | ||
325 | struct hdac_stream *)); | ||
326 | |||
327 | int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus); | ||
328 | void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus); | ||
329 | |||
330 | /* | ||
331 | * macros for easy use | ||
332 | */ | ||
333 | #define _snd_hdac_chip_write(type, chip, reg, value) \ | ||
334 | ((chip)->io_ops->reg_write ## type(value, (chip)->remap_addr + (reg))) | ||
335 | #define _snd_hdac_chip_read(type, chip, reg) \ | ||
336 | ((chip)->io_ops->reg_read ## type((chip)->remap_addr + (reg))) | ||
337 | |||
338 | /* read/write a register, pass without AZX_REG_ prefix */ | ||
339 | #define snd_hdac_chip_writel(chip, reg, value) \ | ||
340 | _snd_hdac_chip_write(l, chip, AZX_REG_ ## reg, value) | ||
341 | #define snd_hdac_chip_writew(chip, reg, value) \ | ||
342 | _snd_hdac_chip_write(w, chip, AZX_REG_ ## reg, value) | ||
343 | #define snd_hdac_chip_writeb(chip, reg, value) \ | ||
344 | _snd_hdac_chip_write(b, chip, AZX_REG_ ## reg, value) | ||
345 | #define snd_hdac_chip_readl(chip, reg) \ | ||
346 | _snd_hdac_chip_read(l, chip, AZX_REG_ ## reg) | ||
347 | #define snd_hdac_chip_readw(chip, reg) \ | ||
348 | _snd_hdac_chip_read(w, chip, AZX_REG_ ## reg) | ||
349 | #define snd_hdac_chip_readb(chip, reg) \ | ||
350 | _snd_hdac_chip_read(b, chip, AZX_REG_ ## reg) | ||
351 | |||
352 | /* update a register, pass without AZX_REG_ prefix */ | ||
353 | #define snd_hdac_chip_updatel(chip, reg, mask, val) \ | ||
354 | snd_hdac_chip_writel(chip, reg, \ | ||
355 | (snd_hdac_chip_readl(chip, reg) & ~(mask)) | (val)) | ||
356 | #define snd_hdac_chip_updatew(chip, reg, mask, val) \ | ||
357 | snd_hdac_chip_writew(chip, reg, \ | ||
358 | (snd_hdac_chip_readw(chip, reg) & ~(mask)) | (val)) | ||
359 | #define snd_hdac_chip_updateb(chip, reg, mask, val) \ | ||
360 | snd_hdac_chip_writeb(chip, reg, \ | ||
361 | (snd_hdac_chip_readb(chip, reg) & ~(mask)) | (val)) | ||
362 | |||
363 | /* | ||
364 | * HD-audio stream | ||
365 | */ | ||
366 | struct hdac_stream { | ||
367 | struct hdac_bus *bus; | ||
368 | struct snd_dma_buffer bdl; /* BDL buffer */ | ||
369 | __le32 *posbuf; /* position buffer pointer */ | ||
370 | int direction; /* playback / capture (SNDRV_PCM_STREAM_*) */ | ||
371 | |||
372 | unsigned int bufsize; /* size of the play buffer in bytes */ | ||
373 | unsigned int period_bytes; /* size of the period in bytes */ | ||
374 | unsigned int frags; /* number for period in the play buffer */ | ||
375 | unsigned int fifo_size; /* FIFO size */ | ||
376 | |||
377 | void __iomem *sd_addr; /* stream descriptor pointer */ | ||
378 | |||
379 | u32 sd_int_sta_mask; /* stream int status mask */ | ||
380 | |||
381 | /* pcm support */ | ||
382 | struct snd_pcm_substream *substream; /* assigned substream, | ||
383 | * set in PCM open | ||
384 | */ | ||
385 | unsigned int format_val; /* format value to be set in the | ||
386 | * controller and the codec | ||
387 | */ | ||
388 | unsigned char stream_tag; /* assigned stream */ | ||
389 | unsigned char index; /* stream index */ | ||
390 | int assigned_key; /* last device# key assigned to */ | ||
391 | |||
392 | bool opened:1; | ||
393 | bool running:1; | ||
394 | bool prepared:1; | ||
395 | bool no_period_wakeup:1; | ||
396 | bool locked:1; | ||
397 | |||
398 | /* timestamp */ | ||
399 | unsigned long start_wallclk; /* start + minimum wallclk */ | ||
400 | unsigned long period_wallclk; /* wallclk for period */ | ||
401 | struct timecounter tc; | ||
402 | struct cyclecounter cc; | ||
403 | int delay_negative_threshold; | ||
404 | |||
405 | struct list_head list; | ||
406 | #ifdef CONFIG_SND_HDA_DSP_LOADER | ||
407 | /* DSP access mutex */ | ||
408 | struct mutex dsp_mutex; | ||
409 | #endif | ||
410 | }; | ||
411 | |||
412 | void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev, | ||
413 | int idx, int direction, int tag); | ||
414 | struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus, | ||
415 | struct snd_pcm_substream *substream); | ||
416 | void snd_hdac_stream_release(struct hdac_stream *azx_dev); | ||
417 | |||
418 | int snd_hdac_stream_setup(struct hdac_stream *azx_dev); | ||
419 | void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev); | ||
420 | int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev); | ||
421 | int snd_hdac_stream_set_params(struct hdac_stream *azx_dev, | ||
422 | unsigned int format_val); | ||
423 | void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start); | ||
424 | void snd_hdac_stream_clear(struct hdac_stream *azx_dev); | ||
425 | void snd_hdac_stream_stop(struct hdac_stream *azx_dev); | ||
426 | void snd_hdac_stream_reset(struct hdac_stream *azx_dev); | ||
427 | void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set, | ||
428 | unsigned int streams, unsigned int reg); | ||
429 | void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, | ||
430 | unsigned int streams); | ||
431 | void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, | ||
432 | unsigned int streams); | ||
433 | /* | ||
434 | * macros for easy use | ||
435 | */ | ||
436 | #define _snd_hdac_stream_write(type, dev, reg, value) \ | ||
437 | ((dev)->bus->io_ops->reg_write ## type(value, (dev)->sd_addr + (reg))) | ||
438 | #define _snd_hdac_stream_read(type, dev, reg) \ | ||
439 | ((dev)->bus->io_ops->reg_read ## type((dev)->sd_addr + (reg))) | ||
440 | |||
441 | /* read/write a register, pass without AZX_REG_ prefix */ | ||
442 | #define snd_hdac_stream_writel(dev, reg, value) \ | ||
443 | _snd_hdac_stream_write(l, dev, AZX_REG_ ## reg, value) | ||
444 | #define snd_hdac_stream_writew(dev, reg, value) \ | ||
445 | _snd_hdac_stream_write(w, dev, AZX_REG_ ## reg, value) | ||
446 | #define snd_hdac_stream_writeb(dev, reg, value) \ | ||
447 | _snd_hdac_stream_write(b, dev, AZX_REG_ ## reg, value) | ||
448 | #define snd_hdac_stream_readl(dev, reg) \ | ||
449 | _snd_hdac_stream_read(l, dev, AZX_REG_ ## reg) | ||
450 | #define snd_hdac_stream_readw(dev, reg) \ | ||
451 | _snd_hdac_stream_read(w, dev, AZX_REG_ ## reg) | ||
452 | #define snd_hdac_stream_readb(dev, reg) \ | ||
453 | _snd_hdac_stream_read(b, dev, AZX_REG_ ## reg) | ||
454 | |||
455 | /* update a register, pass without AZX_REG_ prefix */ | ||
456 | #define snd_hdac_stream_updatel(dev, reg, mask, val) \ | ||
457 | snd_hdac_stream_writel(dev, reg, \ | ||
458 | (snd_hdac_stream_readl(dev, reg) & \ | ||
459 | ~(mask)) | (val)) | ||
460 | #define snd_hdac_stream_updatew(dev, reg, mask, val) \ | ||
461 | snd_hdac_stream_writew(dev, reg, \ | ||
462 | (snd_hdac_stream_readw(dev, reg) & \ | ||
463 | ~(mask)) | (val)) | ||
464 | #define snd_hdac_stream_updateb(dev, reg, mask, val) \ | ||
465 | snd_hdac_stream_writeb(dev, reg, \ | ||
466 | (snd_hdac_stream_readb(dev, reg) & \ | ||
467 | ~(mask)) | (val)) | ||
468 | |||
469 | #ifdef CONFIG_SND_HDA_DSP_LOADER | ||
470 | /* DSP lock helpers */ | ||
471 | #define snd_hdac_dsp_lock_init(dev) mutex_init(&(dev)->dsp_mutex) | ||
472 | #define snd_hdac_dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex) | ||
473 | #define snd_hdac_dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex) | ||
474 | #define snd_hdac_stream_is_locked(dev) ((dev)->locked) | ||
475 | /* DSP loader helpers */ | ||
476 | int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, | ||
477 | unsigned int byte_size, struct snd_dma_buffer *bufp); | ||
478 | void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start); | ||
479 | void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, | ||
480 | struct snd_dma_buffer *dmab); | ||
481 | #else /* CONFIG_SND_HDA_DSP_LOADER */ | ||
482 | #define snd_hdac_dsp_lock_init(dev) do {} while (0) | ||
483 | #define snd_hdac_dsp_lock(dev) do {} while (0) | ||
484 | #define snd_hdac_dsp_unlock(dev) do {} while (0) | ||
485 | #define snd_hdac_stream_is_locked(dev) 0 | ||
486 | |||
487 | static inline int | ||
488 | snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, | ||
489 | unsigned int byte_size, struct snd_dma_buffer *bufp) | ||
490 | { | ||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static inline void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start) | ||
495 | { | ||
496 | } | ||
497 | |||
498 | static inline void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev, | ||
499 | struct snd_dma_buffer *dmab) | ||
500 | { | ||
501 | } | ||
502 | #endif /* CONFIG_SND_HDA_DSP_LOADER */ | ||
503 | |||
504 | |||
225 | /* | 505 | /* |
226 | * generic array helpers | 506 | * generic array helpers |
227 | */ | 507 | */ |