1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 231ef9134SClemens Ladisch #ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED 331ef9134SClemens Ladisch #define SOUND_FIREWIRE_AMDTP_H_INCLUDED 431ef9134SClemens Ladisch 520b65dd0SClemens Ladisch #include <linux/err.h> 676fb8789SClemens Ladisch #include <linux/interrupt.h> 731ef9134SClemens Ladisch #include <linux/mutex.h> 85955815eSTakashi Sakamoto #include <linux/sched.h> 9777fb574STakashi Sakamoto #include <sound/asound.h> 1031ef9134SClemens Ladisch #include "packets-buffer.h" 1131ef9134SClemens Ladisch 1231ef9134SClemens Ladisch /** 13be4a2894STakashi Sakamoto * enum cip_flags - describes details of the streaming protocol 1431ef9134SClemens Ladisch * @CIP_NONBLOCKING: In non-blocking mode, each packet contains 1531ef9134SClemens Ladisch * sample_rate/8000 samples, with rounding up or down to adjust 1631ef9134SClemens Ladisch * for clock skew and left-over fractional samples. This should 1731ef9134SClemens Ladisch * be used if supported by the device. 18e84d15f6SClemens Ladisch * @CIP_BLOCKING: In blocking mode, each packet contains either zero or 19e84d15f6SClemens Ladisch * SYT_INTERVAL samples, with these two types alternating so that 20e84d15f6SClemens Ladisch * the overall sample rate comes out right. 217ab56645STakashi Sakamoto * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. 229dae017bSTakashi Sakamoto * @CIP_DBC_IS_END_EVENT: The value of dbc in an packet corresponds to the end 239dae017bSTakashi Sakamoto * of event in the packet. Out of IEC 61883. 2469702239STakashi Sakamoto * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets. 2569702239STakashi Sakamoto * The value of data_block_quadlets is used instead of reported value. 265f217f90STakashi Sakamoto * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is 27b84b1a27STakashi Sakamoto * skipped for detecting discontinuity. 289d59124cSTakashi Sakamoto * @CIP_EMPTY_HAS_WRONG_DBC: Only for in-stream. The value of dbc in empty 299d59124cSTakashi Sakamoto * packet is wrong but the others are correct. 30a2064710STakashi Sakamoto * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an 31a2064710STakashi Sakamoto * packet is larger than IEC 61883-6 defines. Current implementation 32a2064710STakashi Sakamoto * allows 5 times as large as IEC 61883-6 defines. 332128f78fSTakashi Sakamoto * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include 342128f78fSTakashi Sakamoto * valid EOH. 353b196c39STakashi Sakamoto * @CIP_NO_HEADERS: a lack of headers in packets 36588f2e2cSTakashi Sakamoto * @CIP_UNALIGHED_DBC: Only for in-stream. The value of dbc is not alighed to 37588f2e2cSTakashi Sakamoto * the value of current SYT_INTERVAL; e.g. initial value is not zero. 3831ef9134SClemens Ladisch */ 39be4a2894STakashi Sakamoto enum cip_flags { 40e84d15f6SClemens Ladisch CIP_NONBLOCKING = 0x00, 41e84d15f6SClemens Ladisch CIP_BLOCKING = 0x01, 42dec63cc8STakashi Sakamoto CIP_EMPTY_WITH_TAG0 = 0x02, 43dec63cc8STakashi Sakamoto CIP_DBC_IS_END_EVENT = 0x04, 44dec63cc8STakashi Sakamoto CIP_WRONG_DBS = 0x08, 45dec63cc8STakashi Sakamoto CIP_SKIP_DBC_ZERO_CHECK = 0x10, 4662f00e40STakashi Sakamoto CIP_EMPTY_HAS_WRONG_DBC = 0x20, 4762f00e40STakashi Sakamoto CIP_JUMBO_PAYLOAD = 0x40, 482128f78fSTakashi Sakamoto CIP_HEADER_WITHOUT_EOH = 0x80, 493b196c39STakashi Sakamoto CIP_NO_HEADER = 0x100, 50588f2e2cSTakashi Sakamoto CIP_UNALIGHED_DBC = 0x200, 5131ef9134SClemens Ladisch }; 5231ef9134SClemens Ladisch 5331ef9134SClemens Ladisch /** 545f217f90STakashi Sakamoto * enum cip_sfc - supported Sampling Frequency Codes (SFCs) 555f217f90STakashi Sakamoto * @CIP_SFC_32000: 32,000 data blocks 565f217f90STakashi Sakamoto * @CIP_SFC_44100: 44,100 data blocks 575f217f90STakashi Sakamoto * @CIP_SFC_48000: 48,000 data blocks 585f217f90STakashi Sakamoto * @CIP_SFC_88200: 88,200 data blocks 595f217f90STakashi Sakamoto * @CIP_SFC_96000: 96,000 data blocks 605f217f90STakashi Sakamoto * @CIP_SFC_176400: 176,400 data blocks 615f217f90STakashi Sakamoto * @CIP_SFC_192000: 192,000 data blocks 625f217f90STakashi Sakamoto * @CIP_SFC_COUNT: the number of supported SFCs 635f217f90STakashi Sakamoto * 645f217f90STakashi Sakamoto * These values are used to show nominal Sampling Frequency Code in 655f217f90STakashi Sakamoto * Format Dependent Field (FDF) of AMDTP packet header. In IEC 61883-6:2002, 665f217f90STakashi Sakamoto * this code means the number of events per second. Actually the code 675f217f90STakashi Sakamoto * represents the number of data blocks transferred per second in an AMDTP 685f217f90STakashi Sakamoto * stream. 695f217f90STakashi Sakamoto * 705f217f90STakashi Sakamoto * In IEC 61883-6:2005, some extensions were added to support more types of 715f217f90STakashi Sakamoto * data such as 'One Bit LInear Audio', therefore the meaning of SFC became 725f217f90STakashi Sakamoto * different depending on the types. 735f217f90STakashi Sakamoto * 745f217f90STakashi Sakamoto * Currently our implementation is compatible with IEC 61883-6:2002. 7531ef9134SClemens Ladisch */ 7631ef9134SClemens Ladisch enum cip_sfc { 7731ef9134SClemens Ladisch CIP_SFC_32000 = 0, 7831ef9134SClemens Ladisch CIP_SFC_44100 = 1, 7931ef9134SClemens Ladisch CIP_SFC_48000 = 2, 8031ef9134SClemens Ladisch CIP_SFC_88200 = 3, 8131ef9134SClemens Ladisch CIP_SFC_96000 = 4, 8231ef9134SClemens Ladisch CIP_SFC_176400 = 5, 8331ef9134SClemens Ladisch CIP_SFC_192000 = 6, 84a7304e3bSClemens Ladisch CIP_SFC_COUNT 8531ef9134SClemens Ladisch }; 8631ef9134SClemens Ladisch 8731ef9134SClemens Ladisch struct fw_unit; 8831ef9134SClemens Ladisch struct fw_iso_context; 8931ef9134SClemens Ladisch struct snd_pcm_substream; 907b2d99faSTakashi Sakamoto struct snd_pcm_runtime; 9131ef9134SClemens Ladisch 923ff7e8f0STakashi Sakamoto enum amdtp_stream_direction { 933ff7e8f0STakashi Sakamoto AMDTP_OUT_STREAM = 0, 943ff7e8f0STakashi Sakamoto AMDTP_IN_STREAM 953ff7e8f0STakashi Sakamoto }; 963ff7e8f0STakashi Sakamoto 9704130cf8STakashi Sakamoto struct pkt_desc { 9804130cf8STakashi Sakamoto u32 cycle; 9904130cf8STakashi Sakamoto u32 syt; 10004130cf8STakashi Sakamoto unsigned int data_blocks; 10104130cf8STakashi Sakamoto unsigned int data_block_counter; 10204130cf8STakashi Sakamoto __be32 *ctx_payload; 10304130cf8STakashi Sakamoto }; 10404130cf8STakashi Sakamoto 105df075feeSTakashi Sakamoto struct amdtp_stream; 1069a738ad1STakashi Sakamoto typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)( 107df075feeSTakashi Sakamoto struct amdtp_stream *s, 108d2c104a3STakashi Sakamoto const struct pkt_desc *desc, 1099a738ad1STakashi Sakamoto unsigned int packets, 110d2c104a3STakashi Sakamoto struct snd_pcm_substream *pcm); 1112472cfb3STakashi Sakamoto 1122472cfb3STakashi Sakamoto struct amdtp_domain; 113be4a2894STakashi Sakamoto struct amdtp_stream { 11431ef9134SClemens Ladisch struct fw_unit *unit; 115be4a2894STakashi Sakamoto enum cip_flags flags; 1163ff7e8f0STakashi Sakamoto enum amdtp_stream_direction direction; 11731ef9134SClemens Ladisch struct mutex mutex; 11831ef9134SClemens Ladisch 11910b2b6dcSTakashi Sakamoto /* For packet processing. */ 12010b2b6dcSTakashi Sakamoto struct fw_iso_context *context; 12131ef9134SClemens Ladisch struct iso_packets_buffer buffer; 122a0e02331STakashi Sakamoto unsigned int queue_size; 123ec00f5e4SClemens Ladisch int packet_index; 12404130cf8STakashi Sakamoto struct pkt_desc *pkt_descs; 1253b196c39STakashi Sakamoto int tag; 126d3d10a4aSTakashi Sakamoto union { 127d3d10a4aSTakashi Sakamoto struct { 128d3d10a4aSTakashi Sakamoto unsigned int ctx_header_size; 129d3d10a4aSTakashi Sakamoto 130d3d10a4aSTakashi Sakamoto // limit for payload of iso packet. 131f11453c7STakashi Sakamoto unsigned int max_ctx_payload_length; 13210b2b6dcSTakashi Sakamoto 133d3d10a4aSTakashi Sakamoto // For quirks of CIP headers. 134d3d10a4aSTakashi Sakamoto // Fixed interval of dbc between previos/current 135d3d10a4aSTakashi Sakamoto // packets. 136d3d10a4aSTakashi Sakamoto unsigned int dbc_interval; 137d3d10a4aSTakashi Sakamoto } tx; 138d3d10a4aSTakashi Sakamoto struct { 139d3d10a4aSTakashi Sakamoto // To calculate CIP data blocks and tstamp. 140d3d10a4aSTakashi Sakamoto unsigned int transfer_delay; 1411a4be183STakashi Sakamoto unsigned int seq_index; 1421a4be183STakashi Sakamoto 143d3d10a4aSTakashi Sakamoto // To generate CIP header. 144d3d10a4aSTakashi Sakamoto unsigned int fdf; 1453baf3053STakashi Sakamoto int syt_override; 14660dd4929STakashi Sakamoto 14760dd4929STakashi Sakamoto // To generate constant hardware IRQ. 148e229853dSTakashi Sakamoto unsigned int event_count; 149e229853dSTakashi Sakamoto unsigned int events_per_period; 15060dd4929STakashi Sakamoto } rx; 15160dd4929STakashi Sakamoto } ctx_data; 152d3d10a4aSTakashi Sakamoto 15310b2b6dcSTakashi Sakamoto /* For CIP headers. */ 15410b2b6dcSTakashi Sakamoto unsigned int source_node_id_field; 15510b2b6dcSTakashi Sakamoto unsigned int data_block_quadlets; 15631ef9134SClemens Ladisch unsigned int data_block_counter; 1579863874fSTakashi Sakamoto unsigned int sph; 158414ba022STakashi Sakamoto unsigned int fmt; 159d9cd0065STakashi Sakamoto 16010b2b6dcSTakashi Sakamoto /* Internal flags. */ 16110b2b6dcSTakashi Sakamoto enum cip_sfc sfc; 16210b2b6dcSTakashi Sakamoto unsigned int syt_interval; 16310b2b6dcSTakashi Sakamoto 16410b2b6dcSTakashi Sakamoto /* For a PCM substream processing. */ 16510b2b6dcSTakashi Sakamoto struct snd_pcm_substream *pcm; 166*2b3d2987STakashi Iwai struct work_struct period_work; 1674a9bfafcSTakashi Sakamoto snd_pcm_uframes_t pcm_buffer_pointer; 16810b2b6dcSTakashi Sakamoto unsigned int pcm_period_pointer; 16910b2b6dcSTakashi Sakamoto 17010b2b6dcSTakashi Sakamoto /* To wait for first packet. */ 1717b3b0d85STakashi Sakamoto bool callbacked; 1727b3b0d85STakashi Sakamoto wait_queue_head_t callback_wait; 173a04513f8STakashi Sakamoto u32 start_cycle; 17410b2b6dcSTakashi Sakamoto 175df075feeSTakashi Sakamoto /* For backends to process data blocks. */ 176df075feeSTakashi Sakamoto void *protocol; 1779a738ad1STakashi Sakamoto amdtp_stream_process_ctx_payloads_t process_ctx_payloads; 1786261f90bSTakashi Sakamoto 1796261f90bSTakashi Sakamoto // For domain. 180157a53eeSTakashi Sakamoto int channel; 181157a53eeSTakashi Sakamoto int speed; 1826261f90bSTakashi Sakamoto struct list_head list; 1832472cfb3STakashi Sakamoto struct amdtp_domain *domain; 18431ef9134SClemens Ladisch }; 18531ef9134SClemens Ladisch 186be4a2894STakashi Sakamoto int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, 187df075feeSTakashi Sakamoto enum amdtp_stream_direction dir, enum cip_flags flags, 188df075feeSTakashi Sakamoto unsigned int fmt, 1899a738ad1STakashi Sakamoto amdtp_stream_process_ctx_payloads_t process_ctx_payloads, 190df075feeSTakashi Sakamoto unsigned int protocol_size); 191be4a2894STakashi Sakamoto void amdtp_stream_destroy(struct amdtp_stream *s); 19231ef9134SClemens Ladisch 193df075feeSTakashi Sakamoto int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate, 194df075feeSTakashi Sakamoto unsigned int data_block_quadlets); 195be4a2894STakashi Sakamoto unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); 19631ef9134SClemens Ladisch 197be4a2894STakashi Sakamoto void amdtp_stream_update(struct amdtp_stream *s); 19831ef9134SClemens Ladisch 1997b2d99faSTakashi Sakamoto int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, 2007b2d99faSTakashi Sakamoto struct snd_pcm_runtime *runtime); 201df075feeSTakashi Sakamoto 202be4a2894STakashi Sakamoto void amdtp_stream_pcm_prepare(struct amdtp_stream *s); 203be4a2894STakashi Sakamoto void amdtp_stream_pcm_abort(struct amdtp_stream *s); 20431ef9134SClemens Ladisch 205c5280e99SClemens Ladisch extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; 2061017abedSTakashi Sakamoto extern const unsigned int amdtp_rate_table[CIP_SFC_COUNT]; 207a7304e3bSClemens Ladisch 208be4a2894STakashi Sakamoto /** 209be4a2894STakashi Sakamoto * amdtp_stream_running - check stream is running or not 210be4a2894STakashi Sakamoto * @s: the AMDTP stream 211be4a2894STakashi Sakamoto * 212be4a2894STakashi Sakamoto * If this function returns true, the stream is running. 213be4a2894STakashi Sakamoto */ 214be4a2894STakashi Sakamoto static inline bool amdtp_stream_running(struct amdtp_stream *s) 21520b65dd0SClemens Ladisch { 21620b65dd0SClemens Ladisch return !IS_ERR(s->context); 21720b65dd0SClemens Ladisch } 21820b65dd0SClemens Ladisch 21931ef9134SClemens Ladisch /** 220be4a2894STakashi Sakamoto * amdtp_streaming_error - check for streaming error 221be4a2894STakashi Sakamoto * @s: the AMDTP stream 222ec00f5e4SClemens Ladisch * 223ec00f5e4SClemens Ladisch * If this function returns true, the stream's packet queue has stopped due to 224ec00f5e4SClemens Ladisch * an asynchronous error. 225ec00f5e4SClemens Ladisch */ 226be4a2894STakashi Sakamoto static inline bool amdtp_streaming_error(struct amdtp_stream *s) 227ec00f5e4SClemens Ladisch { 228ec00f5e4SClemens Ladisch return s->packet_index < 0; 229ec00f5e4SClemens Ladisch } 230ec00f5e4SClemens Ladisch 231ec00f5e4SClemens Ladisch /** 23283d8d72dSTakashi Sakamoto * amdtp_stream_pcm_running - check PCM substream is running or not 23383d8d72dSTakashi Sakamoto * @s: the AMDTP stream 23483d8d72dSTakashi Sakamoto * 23583d8d72dSTakashi Sakamoto * If this function returns true, PCM substream in the AMDTP stream is running. 23683d8d72dSTakashi Sakamoto */ 23783d8d72dSTakashi Sakamoto static inline bool amdtp_stream_pcm_running(struct amdtp_stream *s) 23883d8d72dSTakashi Sakamoto { 23983d8d72dSTakashi Sakamoto return !!s->pcm; 24083d8d72dSTakashi Sakamoto } 24183d8d72dSTakashi Sakamoto 24283d8d72dSTakashi Sakamoto /** 243be4a2894STakashi Sakamoto * amdtp_stream_pcm_trigger - start/stop playback from a PCM device 244be4a2894STakashi Sakamoto * @s: the AMDTP stream 24531ef9134SClemens Ladisch * @pcm: the PCM device to be started, or %NULL to stop the current device 24631ef9134SClemens Ladisch * 24731ef9134SClemens Ladisch * Call this function on a running isochronous stream to enable the actual 24831ef9134SClemens Ladisch * transmission of PCM data. This function should be called from the PCM 24931ef9134SClemens Ladisch * device's .trigger callback. 25031ef9134SClemens Ladisch */ 251be4a2894STakashi Sakamoto static inline void amdtp_stream_pcm_trigger(struct amdtp_stream *s, 25231ef9134SClemens Ladisch struct snd_pcm_substream *pcm) 25331ef9134SClemens Ladisch { 2546aa7de05SMark Rutland WRITE_ONCE(s->pcm, pcm); 25531ef9134SClemens Ladisch } 25631ef9134SClemens Ladisch 25731ef9134SClemens Ladisch static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc) 25831ef9134SClemens Ladisch { 25931ef9134SClemens Ladisch return sfc & 1; 26031ef9134SClemens Ladisch } 26131ef9134SClemens Ladisch 2627b3b0d85STakashi Sakamoto /** 2637b3b0d85STakashi Sakamoto * amdtp_stream_wait_callback - sleep till callbacked or timeout 2647b3b0d85STakashi Sakamoto * @s: the AMDTP stream 2657b3b0d85STakashi Sakamoto * @timeout: msec till timeout 2667b3b0d85STakashi Sakamoto * 2677b3b0d85STakashi Sakamoto * If this function return false, the AMDTP stream should be stopped. 2687b3b0d85STakashi Sakamoto */ 2697b3b0d85STakashi Sakamoto static inline bool amdtp_stream_wait_callback(struct amdtp_stream *s, 2707b3b0d85STakashi Sakamoto unsigned int timeout) 2717b3b0d85STakashi Sakamoto { 2727b3b0d85STakashi Sakamoto return wait_event_timeout(s->callback_wait, 2737b3b0d85STakashi Sakamoto s->callbacked == true, 2747b3b0d85STakashi Sakamoto msecs_to_jiffies(timeout)) > 0; 2757b3b0d85STakashi Sakamoto } 2767b3b0d85STakashi Sakamoto 27725babf29STakashi Sakamoto struct seq_desc { 27825babf29STakashi Sakamoto unsigned int syt_offset; 27925babf29STakashi Sakamoto unsigned int data_blocks; 28025babf29STakashi Sakamoto }; 28125babf29STakashi Sakamoto 2823ec3d7a3STakashi Sakamoto struct amdtp_domain { 2833ec3d7a3STakashi Sakamoto struct list_head streams; 284d68c3123STakashi Sakamoto 285d68c3123STakashi Sakamoto unsigned int events_per_period; 286a0e02331STakashi Sakamoto unsigned int events_per_buffer; 28703b4816dSTakashi Sakamoto 28803b4816dSTakashi Sakamoto struct amdtp_stream *irq_target; 28925babf29STakashi Sakamoto 29025babf29STakashi Sakamoto struct seq_desc *seq_descs; 29125babf29STakashi Sakamoto unsigned int seq_size; 29225babf29STakashi Sakamoto unsigned int seq_tail; 2931a4be183STakashi Sakamoto 2941a4be183STakashi Sakamoto unsigned int data_block_state; 2951a4be183STakashi Sakamoto unsigned int syt_offset_state; 2961a4be183STakashi Sakamoto unsigned int last_syt_offset; 2973ec3d7a3STakashi Sakamoto }; 2983ec3d7a3STakashi Sakamoto 2993ec3d7a3STakashi Sakamoto int amdtp_domain_init(struct amdtp_domain *d); 3003ec3d7a3STakashi Sakamoto void amdtp_domain_destroy(struct amdtp_domain *d); 3013ec3d7a3STakashi Sakamoto 302157a53eeSTakashi Sakamoto int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, 303157a53eeSTakashi Sakamoto int channel, int speed); 304157a53eeSTakashi Sakamoto 305acfedcbeSTakashi Sakamoto int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle); 3066261f90bSTakashi Sakamoto void amdtp_domain_stop(struct amdtp_domain *d); 3076261f90bSTakashi Sakamoto 308d68c3123STakashi Sakamoto static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d, 309a0e02331STakashi Sakamoto unsigned int events_per_period, 310a0e02331STakashi Sakamoto unsigned int events_per_buffer) 311d68c3123STakashi Sakamoto { 312d68c3123STakashi Sakamoto d->events_per_period = events_per_period; 313a0e02331STakashi Sakamoto d->events_per_buffer = events_per_buffer; 314d68c3123STakashi Sakamoto 315d68c3123STakashi Sakamoto return 0; 316d68c3123STakashi Sakamoto } 317d68c3123STakashi Sakamoto 318f890f9a0STakashi Sakamoto unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, 319f890f9a0STakashi Sakamoto struct amdtp_stream *s); 320e6dcc92fSTakashi Sakamoto int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s); 321e6dcc92fSTakashi Sakamoto 32231ef9134SClemens Ladisch #endif 323