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