Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /*
3 : : * HD-audio core stuff
4 : : */
5 : :
6 : : #ifndef __SOUND_HDAUDIO_H
7 : : #define __SOUND_HDAUDIO_H
8 : :
9 : : #include <linux/device.h>
10 : : #include <linux/interrupt.h>
11 : : #include <linux/io.h>
12 : : #include <linux/pm_runtime.h>
13 : : #include <linux/timecounter.h>
14 : : #include <sound/core.h>
15 : : #include <sound/pcm.h>
16 : : #include <sound/memalloc.h>
17 : : #include <sound/hda_verbs.h>
18 : : #include <drm/i915_component.h>
19 : :
20 : : /* codec node id */
21 : : typedef u16 hda_nid_t;
22 : :
23 : : struct hdac_bus;
24 : : struct hdac_stream;
25 : : struct hdac_device;
26 : : struct hdac_driver;
27 : : struct hdac_widget_tree;
28 : : struct hda_device_id;
29 : :
30 : : /*
31 : : * exported bus type
32 : : */
33 : : extern struct bus_type snd_hda_bus_type;
34 : :
35 : : /*
36 : : * generic arrays
37 : : */
38 : : struct snd_array {
39 : : unsigned int used;
40 : : unsigned int alloced;
41 : : unsigned int elem_size;
42 : : unsigned int alloc_align;
43 : : void *list;
44 : : };
45 : :
46 : : /*
47 : : * HD-audio codec base device
48 : : */
49 : : struct hdac_device {
50 : : struct device dev;
51 : : int type;
52 : : struct hdac_bus *bus;
53 : : unsigned int addr; /* codec address */
54 : : struct list_head list; /* list point for bus codec_list */
55 : :
56 : : hda_nid_t afg; /* AFG node id */
57 : : hda_nid_t mfg; /* MFG node id */
58 : :
59 : : /* ids */
60 : : unsigned int vendor_id;
61 : : unsigned int subsystem_id;
62 : : unsigned int revision_id;
63 : : unsigned int afg_function_id;
64 : : unsigned int mfg_function_id;
65 : : unsigned int afg_unsol:1;
66 : : unsigned int mfg_unsol:1;
67 : :
68 : : unsigned int power_caps; /* FG power caps */
69 : :
70 : : const char *vendor_name; /* codec vendor name */
71 : : const char *chip_name; /* codec chip name */
72 : :
73 : : /* verb exec op override */
74 : : int (*exec_verb)(struct hdac_device *dev, unsigned int cmd,
75 : : unsigned int flags, unsigned int *res);
76 : :
77 : : /* widgets */
78 : : unsigned int num_nodes;
79 : : hda_nid_t start_nid, end_nid;
80 : :
81 : : /* misc flags */
82 : : atomic_t in_pm; /* suspend/resume being performed */
83 : :
84 : : /* sysfs */
85 : : struct mutex widget_lock;
86 : : struct hdac_widget_tree *widgets;
87 : :
88 : : /* regmap */
89 : : struct regmap *regmap;
90 : : struct mutex regmap_lock;
91 : : struct snd_array vendor_verbs;
92 : : bool lazy_cache:1; /* don't wake up for writes */
93 : : bool caps_overwriting:1; /* caps overwrite being in process */
94 : : bool cache_coef:1; /* cache COEF read/write too */
95 : : };
96 : :
97 : : /* device/driver type used for matching */
98 : : enum {
99 : : HDA_DEV_CORE,
100 : : HDA_DEV_LEGACY,
101 : : HDA_DEV_ASOC,
102 : : };
103 : :
104 : : enum {
105 : : SND_SKL_PCI_BIND_AUTO, /* automatic selection based on pci class */
106 : : SND_SKL_PCI_BIND_LEGACY,/* bind only with legacy driver */
107 : : SND_SKL_PCI_BIND_ASOC /* bind only with ASoC driver */
108 : : };
109 : :
110 : : /* direction */
111 : : enum {
112 : : HDA_INPUT, HDA_OUTPUT
113 : : };
114 : :
115 : : #define dev_to_hdac_dev(_dev) container_of(_dev, struct hdac_device, dev)
116 : :
117 : : int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
118 : : const char *name, unsigned int addr);
119 : : void snd_hdac_device_exit(struct hdac_device *dev);
120 : : int snd_hdac_device_register(struct hdac_device *codec);
121 : : void snd_hdac_device_unregister(struct hdac_device *codec);
122 : : int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
123 : : int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
124 : :
125 : : int snd_hdac_refresh_widgets(struct hdac_device *codec);
126 : :
127 : : int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
128 : : unsigned int verb, unsigned int parm, unsigned int *res);
129 : : int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
130 : : unsigned int *res);
131 : : int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
132 : : int parm);
133 : : int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
134 : : unsigned int parm, unsigned int val);
135 : : int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
136 : : hda_nid_t *conn_list, int max_conns);
137 : : int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
138 : : hda_nid_t *start_id);
139 : : unsigned int snd_hdac_calc_stream_format(unsigned int rate,
140 : : unsigned int channels,
141 : : snd_pcm_format_t format,
142 : : unsigned int maxbps,
143 : : unsigned short spdif_ctls);
144 : : int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
145 : : u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
146 : : bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
147 : : unsigned int format);
148 : :
149 : : int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
150 : : int flags, unsigned int verb, unsigned int parm);
151 : : int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
152 : : int flags, unsigned int verb, unsigned int parm);
153 : : bool snd_hdac_check_power_state(struct hdac_device *hdac,
154 : : hda_nid_t nid, unsigned int target_state);
155 : : unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
156 : : hda_nid_t nid, unsigned int target_state);
157 : : /**
158 : : * snd_hdac_read_parm - read a codec parameter
159 : : * @codec: the codec object
160 : : * @nid: NID to read a parameter
161 : : * @parm: parameter to read
162 : : *
163 : : * Returns -1 for error. If you need to distinguish the error more
164 : : * strictly, use _snd_hdac_read_parm() directly.
165 : : */
166 : 0 : static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
167 : : int parm)
168 : : {
169 : 0 : unsigned int val;
170 : :
171 [ # # # # : 0 : return _snd_hdac_read_parm(codec, nid, parm, &val) < 0 ? -1 : val;
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
172 : : }
173 : :
174 : : #ifdef CONFIG_PM
175 : : int snd_hdac_power_up(struct hdac_device *codec);
176 : : int snd_hdac_power_down(struct hdac_device *codec);
177 : : int snd_hdac_power_up_pm(struct hdac_device *codec);
178 : : int snd_hdac_power_down_pm(struct hdac_device *codec);
179 : : int snd_hdac_keep_power_up(struct hdac_device *codec);
180 : :
181 : : /* call this at entering into suspend/resume callbacks in codec driver */
182 : 0 : static inline void snd_hdac_enter_pm(struct hdac_device *codec)
183 : : {
184 : 0 : atomic_inc(&codec->in_pm);
185 : : }
186 : :
187 : : /* call this at leaving from suspend/resume callbacks in codec driver */
188 : 0 : static inline void snd_hdac_leave_pm(struct hdac_device *codec)
189 : : {
190 : 0 : atomic_dec(&codec->in_pm);
191 : : }
192 : :
193 : 0 : static inline bool snd_hdac_is_in_pm(struct hdac_device *codec)
194 : : {
195 : 0 : return atomic_read(&codec->in_pm);
196 : : }
197 : :
198 : 0 : static inline bool snd_hdac_is_power_on(struct hdac_device *codec)
199 : : {
200 [ # # # # : 0 : return !pm_runtime_suspended(&codec->dev);
# # ]
201 : : }
202 : : #else
203 : : static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
204 : : static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
205 : : static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
206 : : static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
207 : : static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
208 : : static inline void snd_hdac_enter_pm(struct hdac_device *codec) {}
209 : : static inline void snd_hdac_leave_pm(struct hdac_device *codec) {}
210 : : static inline bool snd_hdac_is_in_pm(struct hdac_device *codec) { return 0; }
211 : : static inline bool snd_hdac_is_power_on(struct hdac_device *codec) { return 1; }
212 : : #endif
213 : :
214 : : /*
215 : : * HD-audio codec base driver
216 : : */
217 : : struct hdac_driver {
218 : : struct device_driver driver;
219 : : int type;
220 : : const struct hda_device_id *id_table;
221 : : int (*match)(struct hdac_device *dev, struct hdac_driver *drv);
222 : : void (*unsol_event)(struct hdac_device *dev, unsigned int event);
223 : :
224 : : /* fields used by ext bus APIs */
225 : : int (*probe)(struct hdac_device *dev);
226 : : int (*remove)(struct hdac_device *dev);
227 : : void (*shutdown)(struct hdac_device *dev);
228 : : };
229 : :
230 : : #define drv_to_hdac_driver(_drv) container_of(_drv, struct hdac_driver, driver)
231 : :
232 : : const struct hda_device_id *
233 : : hdac_get_device_id(struct hdac_device *hdev, struct hdac_driver *drv);
234 : :
235 : : /*
236 : : * Bus verb operators
237 : : */
238 : : struct hdac_bus_ops {
239 : : /* send a single command */
240 : : int (*command)(struct hdac_bus *bus, unsigned int cmd);
241 : : /* get a response from the last command */
242 : : int (*get_response)(struct hdac_bus *bus, unsigned int addr,
243 : : unsigned int *res);
244 : : };
245 : :
246 : : /*
247 : : * ops used for ASoC HDA codec drivers
248 : : */
249 : : struct hdac_ext_bus_ops {
250 : : int (*hdev_attach)(struct hdac_device *hdev);
251 : : int (*hdev_detach)(struct hdac_device *hdev);
252 : : };
253 : :
254 : : #define HDA_UNSOL_QUEUE_SIZE 64
255 : : #define HDA_MAX_CODECS 8 /* limit by controller side */
256 : :
257 : : /*
258 : : * CORB/RIRB
259 : : *
260 : : * Each CORB entry is 4byte, RIRB is 8byte
261 : : */
262 : : struct hdac_rb {
263 : : __le32 *buf; /* virtual address of CORB/RIRB buffer */
264 : : dma_addr_t addr; /* physical address of CORB/RIRB buffer */
265 : : unsigned short rp, wp; /* RIRB read/write pointers */
266 : : int cmds[HDA_MAX_CODECS]; /* number of pending requests */
267 : : u32 res[HDA_MAX_CODECS]; /* last read value */
268 : : };
269 : :
270 : : /*
271 : : * HD-audio bus base driver
272 : : *
273 : : * @ppcap: pp capabilities pointer
274 : : * @spbcap: SPIB capabilities pointer
275 : : * @mlcap: MultiLink capabilities pointer
276 : : * @gtscap: gts capabilities pointer
277 : : * @drsmcap: dma resume capabilities pointer
278 : : * @num_streams: streams supported
279 : : * @idx: HDA link index
280 : : * @hlink_list: link list of HDA links
281 : : * @lock: lock for link and display power mgmt
282 : : * @cmd_dma_state: state of cmd DMAs: CORB and RIRB
283 : : */
284 : : struct hdac_bus {
285 : : struct device *dev;
286 : : const struct hdac_bus_ops *ops;
287 : : const struct hdac_ext_bus_ops *ext_ops;
288 : :
289 : : /* h/w resources */
290 : : unsigned long addr;
291 : : void __iomem *remap_addr;
292 : : int irq;
293 : :
294 : : void __iomem *ppcap;
295 : : void __iomem *spbcap;
296 : : void __iomem *mlcap;
297 : : void __iomem *gtscap;
298 : : void __iomem *drsmcap;
299 : :
300 : : /* codec linked list */
301 : : struct list_head codec_list;
302 : : unsigned int num_codecs;
303 : :
304 : : /* link caddr -> codec */
305 : : struct hdac_device *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
306 : :
307 : : /* unsolicited event queue */
308 : : u32 unsol_queue[HDA_UNSOL_QUEUE_SIZE * 2]; /* ring buffer */
309 : : unsigned int unsol_rp, unsol_wp;
310 : : struct work_struct unsol_work;
311 : :
312 : : /* bit flags of detected codecs */
313 : : unsigned long codec_mask;
314 : :
315 : : /* bit flags of powered codecs */
316 : : unsigned long codec_powered;
317 : :
318 : : /* CORB/RIRB */
319 : : struct hdac_rb corb;
320 : : struct hdac_rb rirb;
321 : : unsigned int last_cmd[HDA_MAX_CODECS]; /* last sent command */
322 : : wait_queue_head_t rirb_wq;
323 : :
324 : : /* CORB/RIRB and position buffers */
325 : : struct snd_dma_buffer rb;
326 : : struct snd_dma_buffer posbuf;
327 : : int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */
328 : :
329 : : /* hdac_stream linked list */
330 : : struct list_head stream_list;
331 : :
332 : : /* operation state */
333 : : bool chip_init:1; /* h/w initialized */
334 : :
335 : : /* behavior flags */
336 : : bool aligned_mmio:1; /* aligned MMIO access */
337 : : bool sync_write:1; /* sync after verb write */
338 : : bool use_posbuf:1; /* use position buffer */
339 : : bool snoop:1; /* enable snooping */
340 : : bool align_bdle_4k:1; /* BDLE align 4K boundary */
341 : : bool reverse_assign:1; /* assign devices in reverse order */
342 : : bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
343 : : bool polling_mode:1;
344 : : bool needs_damn_long_delay:1;
345 : :
346 : : int poll_count;
347 : :
348 : : int bdl_pos_adj; /* BDL position adjustment */
349 : :
350 : : /* locks */
351 : : spinlock_t reg_lock;
352 : : struct mutex cmd_mutex;
353 : : struct mutex lock;
354 : :
355 : : /* DRM component interface */
356 : : struct drm_audio_component *audio_component;
357 : : long display_power_status;
358 : : unsigned long display_power_active;
359 : :
360 : : /* parameters required for enhanced capabilities */
361 : : int num_streams;
362 : : int idx;
363 : :
364 : : /* link management */
365 : : struct list_head hlink_list;
366 : : bool cmd_dma_state;
367 : : };
368 : :
369 : : int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
370 : : const struct hdac_bus_ops *ops);
371 : : void snd_hdac_bus_exit(struct hdac_bus *bus);
372 : : int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
373 : : unsigned int cmd, unsigned int *res);
374 : : int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
375 : : unsigned int cmd, unsigned int *res);
376 : : void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
377 : :
378 : 0 : static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
379 : : {
380 : 0 : set_bit(codec->addr, &codec->bus->codec_powered);
381 : : }
382 : :
383 : 0 : static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
384 : : {
385 : 0 : clear_bit(codec->addr, &codec->bus->codec_powered);
386 : 0 : }
387 : :
388 : : int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
389 : : int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
390 : : unsigned int *res);
391 : : int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
392 : :
393 : : bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
394 : : void snd_hdac_bus_stop_chip(struct hdac_bus *bus);
395 : : void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus);
396 : : void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
397 : : void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
398 : : void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
399 : : int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset);
400 : :
401 : : void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
402 : : int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
403 : : void (*ack)(struct hdac_bus *,
404 : : struct hdac_stream *));
405 : :
406 : : int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus);
407 : : void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
408 : :
409 : : #ifdef CONFIG_SND_HDA_ALIGNED_MMIO
410 : : unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask);
411 : : void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
412 : : unsigned int mask);
413 : : #define snd_hdac_aligned_mmio(bus) (bus)->aligned_mmio
414 : : #else
415 : : #define snd_hdac_aligned_mmio(bus) false
416 : : #define snd_hdac_aligned_read(addr, mask) 0
417 : : #define snd_hdac_aligned_write(val, addr, mask) do {} while (0)
418 : : #endif
419 : :
420 : 0 : static inline void snd_hdac_reg_writeb(struct hdac_bus *bus, void __iomem *addr,
421 : : u8 val)
422 : : {
423 : 0 : if (snd_hdac_aligned_mmio(bus))
424 : : snd_hdac_aligned_write(val, addr, 0xff);
425 : : else
426 : 0 : writeb(val, addr);
427 : 0 : }
428 : :
429 : 0 : static inline void snd_hdac_reg_writew(struct hdac_bus *bus, void __iomem *addr,
430 : : u16 val)
431 : : {
432 : 0 : if (snd_hdac_aligned_mmio(bus))
433 : : snd_hdac_aligned_write(val, addr, 0xffff);
434 : : else
435 : 0 : writew(val, addr);
436 : 0 : }
437 : :
438 : 0 : static inline u8 snd_hdac_reg_readb(struct hdac_bus *bus, void __iomem *addr)
439 : : {
440 : 0 : return snd_hdac_aligned_mmio(bus) ?
441 : : snd_hdac_aligned_read(addr, 0xff) : readb(addr);
442 : : }
443 : :
444 : 0 : static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
445 : : {
446 : 0 : return snd_hdac_aligned_mmio(bus) ?
447 : : snd_hdac_aligned_read(addr, 0xffff) : readw(addr);
448 : : }
449 : :
450 : : #define snd_hdac_reg_writel(bus, addr, val) writel(val, addr)
451 : : #define snd_hdac_reg_readl(bus, addr) readl(addr)
452 : :
453 : : /*
454 : : * macros for easy use
455 : : */
456 : : #define _snd_hdac_chip_writeb(chip, reg, value) \
457 : : snd_hdac_reg_writeb(chip, (chip)->remap_addr + (reg), value)
458 : : #define _snd_hdac_chip_readb(chip, reg) \
459 : : snd_hdac_reg_readb(chip, (chip)->remap_addr + (reg))
460 : : #define _snd_hdac_chip_writew(chip, reg, value) \
461 : : snd_hdac_reg_writew(chip, (chip)->remap_addr + (reg), value)
462 : : #define _snd_hdac_chip_readw(chip, reg) \
463 : : snd_hdac_reg_readw(chip, (chip)->remap_addr + (reg))
464 : : #define _snd_hdac_chip_writel(chip, reg, value) \
465 : : snd_hdac_reg_writel(chip, (chip)->remap_addr + (reg), value)
466 : : #define _snd_hdac_chip_readl(chip, reg) \
467 : : snd_hdac_reg_readl(chip, (chip)->remap_addr + (reg))
468 : :
469 : : /* read/write a register, pass without AZX_REG_ prefix */
470 : : #define snd_hdac_chip_writel(chip, reg, value) \
471 : : _snd_hdac_chip_writel(chip, AZX_REG_ ## reg, value)
472 : : #define snd_hdac_chip_writew(chip, reg, value) \
473 : : _snd_hdac_chip_writew(chip, AZX_REG_ ## reg, value)
474 : : #define snd_hdac_chip_writeb(chip, reg, value) \
475 : : _snd_hdac_chip_writeb(chip, AZX_REG_ ## reg, value)
476 : : #define snd_hdac_chip_readl(chip, reg) \
477 : : _snd_hdac_chip_readl(chip, AZX_REG_ ## reg)
478 : : #define snd_hdac_chip_readw(chip, reg) \
479 : : _snd_hdac_chip_readw(chip, AZX_REG_ ## reg)
480 : : #define snd_hdac_chip_readb(chip, reg) \
481 : : _snd_hdac_chip_readb(chip, AZX_REG_ ## reg)
482 : :
483 : : /* update a register, pass without AZX_REG_ prefix */
484 : : #define snd_hdac_chip_updatel(chip, reg, mask, val) \
485 : : snd_hdac_chip_writel(chip, reg, \
486 : : (snd_hdac_chip_readl(chip, reg) & ~(mask)) | (val))
487 : : #define snd_hdac_chip_updatew(chip, reg, mask, val) \
488 : : snd_hdac_chip_writew(chip, reg, \
489 : : (snd_hdac_chip_readw(chip, reg) & ~(mask)) | (val))
490 : : #define snd_hdac_chip_updateb(chip, reg, mask, val) \
491 : : snd_hdac_chip_writeb(chip, reg, \
492 : : (snd_hdac_chip_readb(chip, reg) & ~(mask)) | (val))
493 : :
494 : : /*
495 : : * HD-audio stream
496 : : */
497 : : struct hdac_stream {
498 : : struct hdac_bus *bus;
499 : : struct snd_dma_buffer bdl; /* BDL buffer */
500 : : __le32 *posbuf; /* position buffer pointer */
501 : : int direction; /* playback / capture (SNDRV_PCM_STREAM_*) */
502 : :
503 : : unsigned int bufsize; /* size of the play buffer in bytes */
504 : : unsigned int period_bytes; /* size of the period in bytes */
505 : : unsigned int frags; /* number for period in the play buffer */
506 : : unsigned int fifo_size; /* FIFO size */
507 : :
508 : : void __iomem *sd_addr; /* stream descriptor pointer */
509 : :
510 : : u32 sd_int_sta_mask; /* stream int status mask */
511 : :
512 : : /* pcm support */
513 : : struct snd_pcm_substream *substream; /* assigned substream,
514 : : * set in PCM open
515 : : */
516 : : unsigned int format_val; /* format value to be set in the
517 : : * controller and the codec
518 : : */
519 : : unsigned char stream_tag; /* assigned stream */
520 : : unsigned char index; /* stream index */
521 : : int assigned_key; /* last device# key assigned to */
522 : :
523 : : bool opened:1;
524 : : bool running:1;
525 : : bool prepared:1;
526 : : bool no_period_wakeup:1;
527 : : bool locked:1;
528 : : bool stripe:1; /* apply stripe control */
529 : :
530 : : /* timestamp */
531 : : unsigned long start_wallclk; /* start + minimum wallclk */
532 : : unsigned long period_wallclk; /* wallclk for period */
533 : : struct timecounter tc;
534 : : struct cyclecounter cc;
535 : : int delay_negative_threshold;
536 : :
537 : : struct list_head list;
538 : : #ifdef CONFIG_SND_HDA_DSP_LOADER
539 : : /* DSP access mutex */
540 : : struct mutex dsp_mutex;
541 : : #endif
542 : : };
543 : :
544 : : void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
545 : : int idx, int direction, int tag);
546 : : struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
547 : : struct snd_pcm_substream *substream);
548 : : void snd_hdac_stream_release(struct hdac_stream *azx_dev);
549 : : struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
550 : : int dir, int stream_tag);
551 : :
552 : : int snd_hdac_stream_setup(struct hdac_stream *azx_dev);
553 : : void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev);
554 : : int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev);
555 : : int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
556 : : unsigned int format_val);
557 : : void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
558 : : void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
559 : : void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
560 : : void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
561 : : void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
562 : : unsigned int streams, unsigned int reg);
563 : : void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
564 : : unsigned int streams);
565 : : void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
566 : : unsigned int streams);
567 : : int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
568 : : struct snd_pcm_substream *substream);
569 : :
570 : : /*
571 : : * macros for easy use
572 : : */
573 : : /* read/write a register, pass without AZX_REG_ prefix */
574 : : #define snd_hdac_stream_writel(dev, reg, value) \
575 : : snd_hdac_reg_writel((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
576 : : #define snd_hdac_stream_writew(dev, reg, value) \
577 : : snd_hdac_reg_writew((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
578 : : #define snd_hdac_stream_writeb(dev, reg, value) \
579 : : snd_hdac_reg_writeb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
580 : : #define snd_hdac_stream_readl(dev, reg) \
581 : : snd_hdac_reg_readl((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
582 : : #define snd_hdac_stream_readw(dev, reg) \
583 : : snd_hdac_reg_readw((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
584 : : #define snd_hdac_stream_readb(dev, reg) \
585 : : snd_hdac_reg_readb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
586 : :
587 : : /* update a register, pass without AZX_REG_ prefix */
588 : : #define snd_hdac_stream_updatel(dev, reg, mask, val) \
589 : : snd_hdac_stream_writel(dev, reg, \
590 : : (snd_hdac_stream_readl(dev, reg) & \
591 : : ~(mask)) | (val))
592 : : #define snd_hdac_stream_updatew(dev, reg, mask, val) \
593 : : snd_hdac_stream_writew(dev, reg, \
594 : : (snd_hdac_stream_readw(dev, reg) & \
595 : : ~(mask)) | (val))
596 : : #define snd_hdac_stream_updateb(dev, reg, mask, val) \
597 : : snd_hdac_stream_writeb(dev, reg, \
598 : : (snd_hdac_stream_readb(dev, reg) & \
599 : : ~(mask)) | (val))
600 : :
601 : : #ifdef CONFIG_SND_HDA_DSP_LOADER
602 : : /* DSP lock helpers */
603 : : #define snd_hdac_dsp_lock_init(dev) mutex_init(&(dev)->dsp_mutex)
604 : : #define snd_hdac_dsp_lock(dev) mutex_lock(&(dev)->dsp_mutex)
605 : : #define snd_hdac_dsp_unlock(dev) mutex_unlock(&(dev)->dsp_mutex)
606 : : #define snd_hdac_stream_is_locked(dev) ((dev)->locked)
607 : : /* DSP loader helpers */
608 : : int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
609 : : unsigned int byte_size, struct snd_dma_buffer *bufp);
610 : : void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start);
611 : : void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
612 : : struct snd_dma_buffer *dmab);
613 : : #else /* CONFIG_SND_HDA_DSP_LOADER */
614 : : #define snd_hdac_dsp_lock_init(dev) do {} while (0)
615 : : #define snd_hdac_dsp_lock(dev) do {} while (0)
616 : : #define snd_hdac_dsp_unlock(dev) do {} while (0)
617 : : #define snd_hdac_stream_is_locked(dev) 0
618 : :
619 : : static inline int
620 : : snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
621 : : unsigned int byte_size, struct snd_dma_buffer *bufp)
622 : : {
623 : : return 0;
624 : : }
625 : :
626 : : static inline void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start)
627 : : {
628 : : }
629 : :
630 : : static inline void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
631 : : struct snd_dma_buffer *dmab)
632 : : {
633 : : }
634 : : #endif /* CONFIG_SND_HDA_DSP_LOADER */
635 : :
636 : :
637 : : /*
638 : : * generic array helpers
639 : : */
640 : : void *snd_array_new(struct snd_array *array);
641 : : void snd_array_free(struct snd_array *array);
642 : 0 : static inline void snd_array_init(struct snd_array *array, unsigned int size,
643 : : unsigned int align)
644 : : {
645 : 0 : array->elem_size = size;
646 : 0 : array->alloc_align = align;
647 : : }
648 : :
649 : 0 : static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
650 : : {
651 [ # # # # : 0 : return array->list + idx * array->elem_size;
# # ]
652 : : }
653 : :
654 : : static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
655 : : {
656 : : return (unsigned long)(ptr - array->list) / array->elem_size;
657 : : }
658 : :
659 : : /* a helper macro to iterate for each snd_array element */
660 : : #define snd_array_for_each(array, idx, ptr) \
661 : : for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \
662 : : (ptr) = snd_array_elem(array, ++(idx)))
663 : :
664 : : #endif /* __SOUND_HDAUDIO_H */
|