1 /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ 2 /* Copyright(c) 2015-17 Intel Corporation. */ 3 #include <sound/soc.h> 4 5 #ifndef __SDW_CADENCE_H 6 #define __SDW_CADENCE_H 7 8 #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */ 9 #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) 10 11 /* 12 * The Cadence IP supports up to 32 entries in the FIFO, though implementations 13 * can configure the IP to have a smaller FIFO. 14 */ 15 #define CDNS_MCP_IP_MAX_CMD_LEN 32 16 17 /** 18 * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance 19 * 20 * @num: pdi number 21 * @intel_alh_id: link identifier 22 * @l_ch_num: low channel for PDI 23 * @h_ch_num: high channel for PDI 24 * @ch_count: total channel count for PDI 25 * @dir: data direction 26 * @type: stream type, PDM or PCM 27 */ 28 struct sdw_cdns_pdi { 29 int num; 30 int intel_alh_id; 31 int l_ch_num; 32 int h_ch_num; 33 int ch_count; 34 enum sdw_data_direction dir; 35 enum sdw_stream_type type; 36 }; 37 38 /** 39 * struct sdw_cdns_streams: Cadence stream data structure 40 * 41 * @num_bd: number of bidirectional streams 42 * @num_in: number of input streams 43 * @num_out: number of output streams 44 * @num_ch_bd: number of bidirectional stream channels 45 * @num_ch_bd: number of input stream channels 46 * @num_ch_bd: number of output stream channels 47 * @num_pdi: total number of PDIs 48 * @bd: bidirectional streams 49 * @in: input streams 50 * @out: output streams 51 */ 52 struct sdw_cdns_streams { 53 unsigned int num_bd; 54 unsigned int num_in; 55 unsigned int num_out; 56 unsigned int num_ch_bd; 57 unsigned int num_ch_in; 58 unsigned int num_ch_out; 59 unsigned int num_pdi; 60 struct sdw_cdns_pdi *bd; 61 struct sdw_cdns_pdi *in; 62 struct sdw_cdns_pdi *out; 63 }; 64 65 /** 66 * struct sdw_cdns_stream_config: stream configuration 67 * 68 * @pcm_bd: number of bidirectional PCM streams supported 69 * @pcm_in: number of input PCM streams supported 70 * @pcm_out: number of output PCM streams supported 71 * @pdm_bd: number of bidirectional PDM streams supported 72 * @pdm_in: number of input PDM streams supported 73 * @pdm_out: number of output PDM streams supported 74 */ 75 struct sdw_cdns_stream_config { 76 unsigned int pcm_bd; 77 unsigned int pcm_in; 78 unsigned int pcm_out; 79 unsigned int pdm_bd; 80 unsigned int pdm_in; 81 unsigned int pdm_out; 82 }; 83 84 /** 85 * struct sdw_cdns_dma_data: Cadence DMA data 86 * 87 * @name: SoundWire stream name 88 * @stream: stream runtime 89 * @pdi: PDI used for this dai 90 * @bus: Bus handle 91 * @stream_type: Stream type 92 * @link_id: Master link id 93 * @hw_params: hw_params to be applied in .prepare step 94 * @suspended: status set when suspended, to be used in .prepare 95 */ 96 struct sdw_cdns_dma_data { 97 char *name; 98 struct sdw_stream_runtime *stream; 99 struct sdw_cdns_pdi *pdi; 100 struct sdw_bus *bus; 101 enum sdw_stream_type stream_type; 102 int link_id; 103 struct snd_pcm_hw_params *hw_params; 104 bool suspended; 105 }; 106 107 /** 108 * struct sdw_cdns - Cadence driver context 109 * @dev: Linux device 110 * @bus: Bus handle 111 * @instance: instance number 112 * @response_buf: SoundWire response buffer 113 * @tx_complete: Tx completion 114 * @defer: Defer pointer 115 * @ports: Data ports 116 * @num_ports: Total number of data ports 117 * @pcm: PCM streams 118 * @pdm: PDM streams 119 * @registers: Cadence registers 120 * @link_up: Link status 121 * @msg_count: Messages sent on bus 122 */ 123 struct sdw_cdns { 124 struct device *dev; 125 struct sdw_bus bus; 126 unsigned int instance; 127 128 /* 129 * The datasheet says the RX FIFO AVAIL can be 2 entries more 130 * than the FIFO capacity, so allow for this. 131 */ 132 u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2]; 133 134 struct completion tx_complete; 135 struct sdw_defer *defer; 136 137 struct sdw_cdns_port *ports; 138 int num_ports; 139 140 struct sdw_cdns_streams pcm; 141 struct sdw_cdns_streams pdm; 142 143 int pdi_loopback_source; 144 int pdi_loopback_target; 145 146 void __iomem *registers; 147 148 bool link_up; 149 unsigned int msg_count; 150 bool interrupt_enabled; 151 152 struct work_struct work; 153 154 struct list_head list; 155 }; 156 157 #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus) 158 159 /* Exported symbols */ 160 161 int sdw_cdns_probe(struct sdw_cdns *cdns); 162 extern struct sdw_master_ops sdw_cdns_master_ops; 163 164 irqreturn_t sdw_cdns_irq(int irq, void *dev_id); 165 irqreturn_t sdw_cdns_thread(int irq, void *dev_id); 166 167 int sdw_cdns_init(struct sdw_cdns *cdns); 168 int sdw_cdns_pdi_init(struct sdw_cdns *cdns, 169 struct sdw_cdns_stream_config config); 170 int sdw_cdns_exit_reset(struct sdw_cdns *cdns); 171 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state); 172 173 bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns); 174 int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake); 175 int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset); 176 177 #ifdef CONFIG_DEBUG_FS 178 void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root); 179 #endif 180 181 struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, 182 struct sdw_cdns_streams *stream, 183 u32 ch, u32 dir, int dai_id); 184 void sdw_cdns_config_stream(struct sdw_cdns *cdns, 185 u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); 186 187 enum sdw_command_response 188 cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num); 189 190 enum sdw_command_response 191 cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg); 192 193 enum sdw_command_response 194 cdns_xfer_msg_defer(struct sdw_bus *bus, 195 struct sdw_msg *msg, struct sdw_defer *defer); 196 197 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params); 198 199 int cdns_set_sdw_stream(struct snd_soc_dai *dai, 200 void *stream, bool pcm, int direction); 201 202 void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string, 203 bool initial_delay, int reset_iterations); 204 205 #endif /* __SDW_CADENCE_H */ 206