diff options
Diffstat (limited to 'sound/firewire/amdtp-stream.h')
-rw-r--r-- | sound/firewire/amdtp-stream.h | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index 3942894c11ac..f2d44e2dc3c8 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -33,6 +33,8 @@ * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include * valid EOH. * @CIP_NO_HEADERS: a lack of headers in packets + * @CIP_UNALIGHED_DBC: Only for in-stream. The value of dbc is not alighed to + * the value of current SYT_INTERVAL; e.g. initial value is not zero. */ enum cip_flags { CIP_NONBLOCKING = 0x00, @@ -45,6 +47,7 @@ enum cip_flags { CIP_JUMBO_PAYLOAD = 0x40, CIP_HEADER_WITHOUT_EOH = 0x80, CIP_NO_HEADER = 0x100, + CIP_UNALIGHED_DBC = 0x200, }; /** @@ -91,12 +94,20 @@ enum amdtp_stream_direction { AMDTP_IN_STREAM }; +struct pkt_desc { + u32 cycle; + u32 syt; + unsigned int data_blocks; + unsigned int data_block_counter; + __be32 *ctx_payload; +}; + struct amdtp_stream; -typedef unsigned int (*amdtp_stream_process_data_blocks_t)( +typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)( struct amdtp_stream *s, - __be32 *buffer, - unsigned int data_blocks, - unsigned int *syt); + const struct pkt_desc *desc, + unsigned int packets, + struct snd_pcm_substream *pcm); struct amdtp_stream { struct fw_unit *unit; enum cip_flags flags; @@ -106,7 +117,9 @@ struct amdtp_stream { /* For packet processing. */ struct fw_iso_context *context; struct iso_packets_buffer buffer; + unsigned int queue_size; int packet_index; + struct pkt_desc *pkt_descs; int tag; union { struct { @@ -119,8 +132,6 @@ struct amdtp_stream { // Fixed interval of dbc between previos/current // packets. unsigned int dbc_interval; - // Indicate the value of dbc field in a first packet. - unsigned int first_dbc; } tx; struct { // To calculate CIP data blocks and tstamp. @@ -131,6 +142,11 @@ struct amdtp_stream { // To generate CIP header. unsigned int fdf; + int syt_override; + + // To generate constant hardware IRQ. + unsigned int event_count; + unsigned int events_per_period; } rx; } ctx_data; @@ -158,13 +174,18 @@ struct amdtp_stream { /* For backends to process data blocks. */ void *protocol; - amdtp_stream_process_data_blocks_t process_data_blocks; + amdtp_stream_process_ctx_payloads_t process_ctx_payloads; + + // For domain. + int channel; + int speed; + struct list_head list; }; int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir, enum cip_flags flags, unsigned int fmt, - amdtp_stream_process_data_blocks_t process_data_blocks, + amdtp_stream_process_ctx_payloads_t process_ctx_payloads, unsigned int protocol_size); void amdtp_stream_destroy(struct amdtp_stream *s); @@ -172,16 +193,12 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate, unsigned int data_block_quadlets); unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); -int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed); void amdtp_stream_update(struct amdtp_stream *s); -void amdtp_stream_stop(struct amdtp_stream *s); int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, struct snd_pcm_runtime *runtime); void amdtp_stream_pcm_prepare(struct amdtp_stream *s); -unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); -int amdtp_stream_pcm_ack(struct amdtp_stream *s); void amdtp_stream_pcm_abort(struct amdtp_stream *s); extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; @@ -256,4 +273,36 @@ static inline bool amdtp_stream_wait_callback(struct amdtp_stream *s, msecs_to_jiffies(timeout)) > 0; } +struct amdtp_domain { + struct list_head streams; + + unsigned int events_per_period; + unsigned int events_per_buffer; + + struct amdtp_stream *irq_target; +}; + +int amdtp_domain_init(struct amdtp_domain *d); +void amdtp_domain_destroy(struct amdtp_domain *d); + +int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, + int channel, int speed); + +int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle); +void amdtp_domain_stop(struct amdtp_domain *d); + +static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d, + unsigned int events_per_period, + unsigned int events_per_buffer) +{ + d->events_per_period = events_per_period; + d->events_per_buffer = events_per_buffer; + + return 0; +} + +unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, + struct amdtp_stream *s); +int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s); + #endif |