summaryrefslogtreecommitdiffstats
path: root/drivers/soundwire/intel.h
blob: de9883313c8f28a26533dcbc9a1ccd3b17aec88e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* Copyright(c) 2015-17 Intel Corporation. */

#ifndef __SDW_INTEL_LOCAL_H
#define __SDW_INTEL_LOCAL_H

/**
 * struct sdw_intel_link_res - Soundwire Intel link resource structure,
 * typically populated by the controller driver.
 * @hw_ops: platform-specific ops
 * @mmio_base: mmio base of SoundWire registers
 * @registers: Link IO registers base
 * @shim: Audio shim pointer
 * @alh: ALH (Audio Link Hub) pointer
 * @irq: Interrupt line
 * @ops: Shim callback ops
 * @dev: device implementing hw_params and free callbacks
 * @shim_lock: mutex to handle access to shared SHIM registers
 * @shim_mask: global pointer to check SHIM register initialization
 * @clock_stop_quirks: mask defining requested behavior on pm_suspend
 * @link_mask: global mask needed for power-up/down sequences
 * @cdns: Cadence master descriptor
 * @list: used to walk-through all masters exposed by the same controller
 */
struct sdw_intel_link_res {
	const struct sdw_intel_hw_ops *hw_ops;

	void __iomem *mmio_base; /* not strictly needed, useful for debug */
	void __iomem *registers;
	void __iomem *shim;
	void __iomem *alh;
	int irq;
	const struct sdw_intel_ops *ops;
	struct device *dev;
	struct mutex *shim_lock; /* protect shared registers */
	u32 *shim_mask;
	u32 clock_stop_quirks;
	u32 link_mask;
	struct sdw_cdns *cdns;
	struct list_head list;
};

struct sdw_intel {
	struct sdw_cdns cdns;
	int instance;
	struct sdw_intel_link_res *link_res;
	bool startup_done;
#ifdef CONFIG_DEBUG_FS
	struct dentry *debugfs;
#endif
};

#define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)

#define INTEL_MASTER_RESET_ITERATIONS	10

#define SDW_INTEL_CHECK_OPS(sdw, cb)	((sdw) && (sdw)->link_res && (sdw)->link_res->hw_ops && \
					 (sdw)->link_res->hw_ops->cb)
#define SDW_INTEL_OPS(sdw, cb)		((sdw)->link_res->hw_ops->cb)

static inline void sdw_intel_debugfs_init(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, debugfs_init))
		SDW_INTEL_OPS(sdw, debugfs_init)(sdw);
}

static inline void sdw_intel_debugfs_exit(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, debugfs_exit))
		SDW_INTEL_OPS(sdw, debugfs_exit)(sdw);
}

static inline int sdw_intel_register_dai(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, register_dai))
		return SDW_INTEL_OPS(sdw, register_dai)(sdw);
	return -ENOTSUPP;
}

static inline void sdw_intel_check_clock_stop(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, check_clock_stop))
		SDW_INTEL_OPS(sdw, check_clock_stop)(sdw);
}

static inline int sdw_intel_start_bus(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, start_bus))
		return SDW_INTEL_OPS(sdw, start_bus)(sdw);
	return -ENOTSUPP;
}

static inline int sdw_intel_start_bus_after_reset(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_reset))
		return SDW_INTEL_OPS(sdw, start_bus_after_reset)(sdw);
	return -ENOTSUPP;
}

static inline int sdw_intel_start_bus_after_clock_stop(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, start_bus_after_clock_stop))
		return SDW_INTEL_OPS(sdw, start_bus_after_clock_stop)(sdw);
	return -ENOTSUPP;
}

static inline int sdw_intel_stop_bus(struct sdw_intel *sdw, bool clock_stop)
{
	if (SDW_INTEL_CHECK_OPS(sdw, stop_bus))
		return SDW_INTEL_OPS(sdw, stop_bus)(sdw, clock_stop);
	return -ENOTSUPP;
}

static inline int sdw_intel_link_power_up(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, link_power_up))
		return SDW_INTEL_OPS(sdw, link_power_up)(sdw);
	return -ENOTSUPP;
}

static inline int sdw_intel_link_power_down(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, link_power_down))
		return SDW_INTEL_OPS(sdw, link_power_down)(sdw);
	return -ENOTSUPP;
}

static inline int sdw_intel_shim_check_wake(struct sdw_intel *sdw)
{
	if (SDW_INTEL_CHECK_OPS(sdw, shim_check_wake))
		return SDW_INTEL_OPS(sdw, shim_check_wake)(sdw);
	return -ENOTSUPP;
}

static inline void sdw_intel_shim_wake(struct sdw_intel *sdw, bool wake_enable)
{
	if (SDW_INTEL_CHECK_OPS(sdw, shim_wake))
		SDW_INTEL_OPS(sdw, shim_wake)(sdw, wake_enable);
}

#endif /* __SDW_INTEL_LOCAL_H */