.. | .. |
---|
1 | | -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) |
---|
2 | | -// Copyright(c) 2015-17 Intel Corporation. |
---|
| 1 | +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ |
---|
| 2 | +/* Copyright(c) 2015-17 Intel Corporation. */ |
---|
3 | 3 | |
---|
4 | 4 | #ifndef __SDW_INTEL_H |
---|
5 | 5 | #define __SDW_INTEL_H |
---|
6 | 6 | |
---|
| 7 | +#include <linux/irqreturn.h> |
---|
| 8 | +#include <linux/soundwire/sdw.h> |
---|
| 9 | + |
---|
7 | 10 | /** |
---|
8 | | - * struct sdw_intel_ops: Intel audio driver callback ops |
---|
9 | | - * |
---|
10 | | - * @config_stream: configure the stream with the hw_params |
---|
| 11 | + * struct sdw_intel_stream_params_data: configuration passed during |
---|
| 12 | + * the @params_stream callback, e.g. for interaction with DSP |
---|
| 13 | + * firmware. |
---|
11 | 14 | */ |
---|
12 | | -struct sdw_intel_ops { |
---|
13 | | - int (*config_stream)(void *arg, void *substream, |
---|
14 | | - void *dai, void *hw_params, int stream_num); |
---|
| 15 | +struct sdw_intel_stream_params_data { |
---|
| 16 | + struct snd_pcm_substream *substream; |
---|
| 17 | + struct snd_soc_dai *dai; |
---|
| 18 | + struct snd_pcm_hw_params *hw_params; |
---|
| 19 | + int link_id; |
---|
| 20 | + int alh_stream_id; |
---|
15 | 21 | }; |
---|
16 | 22 | |
---|
17 | 23 | /** |
---|
18 | | - * struct sdw_intel_res - Soundwire Intel resource structure |
---|
| 24 | + * struct sdw_intel_stream_free_data: configuration passed during |
---|
| 25 | + * the @free_stream callback, e.g. for interaction with DSP |
---|
| 26 | + * firmware. |
---|
| 27 | + */ |
---|
| 28 | +struct sdw_intel_stream_free_data { |
---|
| 29 | + struct snd_pcm_substream *substream; |
---|
| 30 | + struct snd_soc_dai *dai; |
---|
| 31 | + int link_id; |
---|
| 32 | +}; |
---|
| 33 | + |
---|
| 34 | +/** |
---|
| 35 | + * struct sdw_intel_ops: Intel audio driver callback ops |
---|
| 36 | + * |
---|
| 37 | + */ |
---|
| 38 | +struct sdw_intel_ops { |
---|
| 39 | + int (*params_stream)(struct device *dev, |
---|
| 40 | + struct sdw_intel_stream_params_data *params_data); |
---|
| 41 | + int (*free_stream)(struct device *dev, |
---|
| 42 | + struct sdw_intel_stream_free_data *free_data); |
---|
| 43 | +}; |
---|
| 44 | + |
---|
| 45 | +/** |
---|
| 46 | + * struct sdw_intel_acpi_info - Soundwire Intel information found in ACPI tables |
---|
| 47 | + * @handle: ACPI controller handle |
---|
| 48 | + * @count: link count found with "sdw-master-count" property |
---|
| 49 | + * @link_mask: bit-wise mask listing links enabled by BIOS menu |
---|
| 50 | + * |
---|
| 51 | + * this structure could be expanded to e.g. provide all the _ADR |
---|
| 52 | + * information in case the link_mask is not sufficient to identify |
---|
| 53 | + * platform capabilities. |
---|
| 54 | + */ |
---|
| 55 | +struct sdw_intel_acpi_info { |
---|
| 56 | + acpi_handle handle; |
---|
| 57 | + int count; |
---|
| 58 | + u32 link_mask; |
---|
| 59 | +}; |
---|
| 60 | + |
---|
| 61 | +struct sdw_intel_link_res; |
---|
| 62 | + |
---|
| 63 | +/* Intel clock-stop/pm_runtime quirk definitions */ |
---|
| 64 | + |
---|
| 65 | +/* |
---|
| 66 | + * Force the clock to remain on during pm_runtime suspend. This might |
---|
| 67 | + * be needed if Slave devices do not have an alternate clock source or |
---|
| 68 | + * if the latency requirements are very strict. |
---|
| 69 | + */ |
---|
| 70 | +#define SDW_INTEL_CLK_STOP_NOT_ALLOWED BIT(0) |
---|
| 71 | + |
---|
| 72 | +/* |
---|
| 73 | + * Stop the bus during pm_runtime suspend. If set, a complete bus |
---|
| 74 | + * reset and re-enumeration will be performed when the bus |
---|
| 75 | + * restarts. This mode shall not be used if Slave devices can generate |
---|
| 76 | + * in-band wakes. |
---|
| 77 | + */ |
---|
| 78 | +#define SDW_INTEL_CLK_STOP_TEARDOWN BIT(1) |
---|
| 79 | + |
---|
| 80 | +/* |
---|
| 81 | + * Stop the bus during pm_suspend if Slaves are not wake capable |
---|
| 82 | + * (e.g. speaker amplifiers). The clock-stop mode is typically |
---|
| 83 | + * slightly higher power than when the IP is completely powered-off. |
---|
| 84 | + */ |
---|
| 85 | +#define SDW_INTEL_CLK_STOP_WAKE_CAPABLE_ONLY BIT(2) |
---|
| 86 | + |
---|
| 87 | +/* |
---|
| 88 | + * Require a bus reset (and complete re-enumeration) when exiting |
---|
| 89 | + * clock stop modes. This may be needed if the controller power was |
---|
| 90 | + * turned off and all context lost. This quirk shall not be used if a |
---|
| 91 | + * Slave device needs to remain enumerated and keep its context, |
---|
| 92 | + * e.g. to provide the reasons for the wake, report acoustic events or |
---|
| 93 | + * pass a history buffer. |
---|
| 94 | + */ |
---|
| 95 | +#define SDW_INTEL_CLK_STOP_BUS_RESET BIT(3) |
---|
| 96 | + |
---|
| 97 | +struct sdw_intel_slave_id { |
---|
| 98 | + int link_id; |
---|
| 99 | + struct sdw_slave_id id; |
---|
| 100 | +}; |
---|
| 101 | + |
---|
| 102 | +/** |
---|
| 103 | + * struct sdw_intel_ctx - context allocated by the controller |
---|
| 104 | + * driver probe |
---|
| 105 | + * @count: link count |
---|
| 106 | + * @mmio_base: mmio base of SoundWire registers, only used to check |
---|
| 107 | + * hardware capabilities after all power dependencies are settled. |
---|
| 108 | + * @link_mask: bit-wise mask listing SoundWire links reported by the |
---|
| 109 | + * Controller |
---|
| 110 | + * @num_slaves: total number of devices exposed across all enabled links |
---|
| 111 | + * @handle: ACPI parent handle |
---|
| 112 | + * @links: information for each link (controller-specific and kept |
---|
| 113 | + * opaque here) |
---|
| 114 | + * @ids: array of slave_id, representing Slaves exposed across all enabled |
---|
| 115 | + * links |
---|
| 116 | + * @link_list: list to handle interrupts across all links |
---|
| 117 | + * @shim_lock: mutex to handle concurrent rmw access to shared SHIM registers. |
---|
| 118 | + * @shim_mask: flags to track initialization of SHIM shared registers |
---|
| 119 | + */ |
---|
| 120 | +struct sdw_intel_ctx { |
---|
| 121 | + int count; |
---|
| 122 | + void __iomem *mmio_base; |
---|
| 123 | + u32 link_mask; |
---|
| 124 | + int num_slaves; |
---|
| 125 | + acpi_handle handle; |
---|
| 126 | + struct sdw_intel_link_res *links; |
---|
| 127 | + struct sdw_intel_slave_id *ids; |
---|
| 128 | + struct list_head link_list; |
---|
| 129 | + struct mutex shim_lock; /* lock for access to shared SHIM registers */ |
---|
| 130 | + u32 shim_mask; |
---|
| 131 | +}; |
---|
| 132 | + |
---|
| 133 | +/** |
---|
| 134 | + * struct sdw_intel_res - Soundwire Intel global resource structure, |
---|
| 135 | + * typically populated by the DSP driver |
---|
| 136 | + * |
---|
| 137 | + * @count: link count |
---|
19 | 138 | * @mmio_base: mmio base of SoundWire registers |
---|
20 | 139 | * @irq: interrupt number |
---|
21 | 140 | * @handle: ACPI parent handle |
---|
22 | 141 | * @parent: parent device |
---|
23 | 142 | * @ops: callback ops |
---|
24 | | - * @arg: callback arg |
---|
| 143 | + * @dev: device implementing hwparams and free callbacks |
---|
| 144 | + * @link_mask: bit-wise mask listing links selected by the DSP driver |
---|
| 145 | + * This mask may be a subset of the one reported by the controller since |
---|
| 146 | + * machine-specific quirks are handled in the DSP driver. |
---|
| 147 | + * @clock_stop_quirks: mask array of possible behaviors requested by the |
---|
| 148 | + * DSP driver. The quirks are common for all links for now. |
---|
25 | 149 | */ |
---|
26 | 150 | struct sdw_intel_res { |
---|
| 151 | + int count; |
---|
27 | 152 | void __iomem *mmio_base; |
---|
28 | 153 | int irq; |
---|
29 | 154 | acpi_handle handle; |
---|
30 | 155 | struct device *parent; |
---|
31 | 156 | const struct sdw_intel_ops *ops; |
---|
32 | | - void *arg; |
---|
| 157 | + struct device *dev; |
---|
| 158 | + u32 link_mask; |
---|
| 159 | + u32 clock_stop_quirks; |
---|
33 | 160 | }; |
---|
34 | 161 | |
---|
35 | | -void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res); |
---|
36 | | -void sdw_intel_exit(void *arg); |
---|
| 162 | +/* |
---|
| 163 | + * On Intel platforms, the SoundWire IP has dependencies on power |
---|
| 164 | + * rails shared with the DSP, and the initialization steps are split |
---|
| 165 | + * in three. First an ACPI scan to check what the firmware describes |
---|
| 166 | + * in DSDT tables, then an allocation step (with no hardware |
---|
| 167 | + * configuration but with all the relevant devices created) and last |
---|
| 168 | + * the actual hardware configuration. The final stage is a global |
---|
| 169 | + * interrupt enable which is controlled by the DSP driver. Splitting |
---|
| 170 | + * these phases helps simplify the boot flow and make early decisions |
---|
| 171 | + * on e.g. which machine driver to select (I2S mode, HDaudio or |
---|
| 172 | + * SoundWire). |
---|
| 173 | + */ |
---|
| 174 | +int sdw_intel_acpi_scan(acpi_handle *parent_handle, |
---|
| 175 | + struct sdw_intel_acpi_info *info); |
---|
| 176 | + |
---|
| 177 | +void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx); |
---|
| 178 | + |
---|
| 179 | +struct sdw_intel_ctx * |
---|
| 180 | +sdw_intel_probe(struct sdw_intel_res *res); |
---|
| 181 | + |
---|
| 182 | +int sdw_intel_startup(struct sdw_intel_ctx *ctx); |
---|
| 183 | + |
---|
| 184 | +void sdw_intel_exit(struct sdw_intel_ctx *ctx); |
---|
| 185 | + |
---|
| 186 | +void sdw_intel_enable_irq(void __iomem *mmio_base, bool enable); |
---|
| 187 | + |
---|
| 188 | +irqreturn_t sdw_intel_thread(int irq, void *dev_id); |
---|
37 | 189 | |
---|
38 | 190 | #endif |
---|