| .. | .. |
|---|
| 33 | 33 | * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include |
|---|
| 34 | 34 | * valid EOH. |
|---|
| 35 | 35 | * @CIP_NO_HEADERS: a lack of headers in packets |
|---|
| 36 | + * @CIP_UNALIGHED_DBC: Only for in-stream. The value of dbc is not alighed to |
|---|
| 37 | + * the value of current SYT_INTERVAL; e.g. initial value is not zero. |
|---|
| 36 | 38 | */ |
|---|
| 37 | 39 | enum cip_flags { |
|---|
| 38 | 40 | CIP_NONBLOCKING = 0x00, |
|---|
| .. | .. |
|---|
| 45 | 47 | CIP_JUMBO_PAYLOAD = 0x40, |
|---|
| 46 | 48 | CIP_HEADER_WITHOUT_EOH = 0x80, |
|---|
| 47 | 49 | CIP_NO_HEADER = 0x100, |
|---|
| 50 | + CIP_UNALIGHED_DBC = 0x200, |
|---|
| 48 | 51 | }; |
|---|
| 49 | 52 | |
|---|
| 50 | 53 | /** |
|---|
| .. | .. |
|---|
| 91 | 94 | AMDTP_IN_STREAM |
|---|
| 92 | 95 | }; |
|---|
| 93 | 96 | |
|---|
| 97 | +struct pkt_desc { |
|---|
| 98 | + u32 cycle; |
|---|
| 99 | + u32 syt; |
|---|
| 100 | + unsigned int data_blocks; |
|---|
| 101 | + unsigned int data_block_counter; |
|---|
| 102 | + __be32 *ctx_payload; |
|---|
| 103 | +}; |
|---|
| 104 | + |
|---|
| 94 | 105 | struct amdtp_stream; |
|---|
| 95 | | -typedef unsigned int (*amdtp_stream_process_data_blocks_t)( |
|---|
| 106 | +typedef unsigned int (*amdtp_stream_process_ctx_payloads_t)( |
|---|
| 96 | 107 | struct amdtp_stream *s, |
|---|
| 97 | | - __be32 *buffer, |
|---|
| 98 | | - unsigned int data_blocks, |
|---|
| 99 | | - unsigned int *syt); |
|---|
| 108 | + const struct pkt_desc *desc, |
|---|
| 109 | + unsigned int packets, |
|---|
| 110 | + struct snd_pcm_substream *pcm); |
|---|
| 111 | + |
|---|
| 112 | +struct amdtp_domain; |
|---|
| 100 | 113 | struct amdtp_stream { |
|---|
| 101 | 114 | struct fw_unit *unit; |
|---|
| 102 | 115 | enum cip_flags flags; |
|---|
| .. | .. |
|---|
| 106 | 119 | /* For packet processing. */ |
|---|
| 107 | 120 | struct fw_iso_context *context; |
|---|
| 108 | 121 | struct iso_packets_buffer buffer; |
|---|
| 122 | + unsigned int queue_size; |
|---|
| 109 | 123 | int packet_index; |
|---|
| 124 | + struct pkt_desc *pkt_descs; |
|---|
| 110 | 125 | int tag; |
|---|
| 111 | | - int (*handle_packet)(struct amdtp_stream *s, |
|---|
| 112 | | - unsigned int payload_quadlets, unsigned int cycle, |
|---|
| 113 | | - unsigned int index); |
|---|
| 114 | | - unsigned int max_payload_length; |
|---|
| 126 | + union { |
|---|
| 127 | + struct { |
|---|
| 128 | + unsigned int ctx_header_size; |
|---|
| 129 | + |
|---|
| 130 | + // limit for payload of iso packet. |
|---|
| 131 | + unsigned int max_ctx_payload_length; |
|---|
| 132 | + |
|---|
| 133 | + // For quirks of CIP headers. |
|---|
| 134 | + // Fixed interval of dbc between previos/current |
|---|
| 135 | + // packets. |
|---|
| 136 | + unsigned int dbc_interval; |
|---|
| 137 | + } tx; |
|---|
| 138 | + struct { |
|---|
| 139 | + // To calculate CIP data blocks and tstamp. |
|---|
| 140 | + unsigned int transfer_delay; |
|---|
| 141 | + unsigned int seq_index; |
|---|
| 142 | + |
|---|
| 143 | + // To generate CIP header. |
|---|
| 144 | + unsigned int fdf; |
|---|
| 145 | + int syt_override; |
|---|
| 146 | + |
|---|
| 147 | + // To generate constant hardware IRQ. |
|---|
| 148 | + unsigned int event_count; |
|---|
| 149 | + unsigned int events_per_period; |
|---|
| 150 | + } rx; |
|---|
| 151 | + } ctx_data; |
|---|
| 115 | 152 | |
|---|
| 116 | 153 | /* For CIP headers. */ |
|---|
| 117 | 154 | unsigned int source_node_id_field; |
|---|
| .. | .. |
|---|
| 119 | 156 | unsigned int data_block_counter; |
|---|
| 120 | 157 | unsigned int sph; |
|---|
| 121 | 158 | unsigned int fmt; |
|---|
| 122 | | - unsigned int fdf; |
|---|
| 123 | | - /* quirk: fixed interval of dbc between previos/current packets. */ |
|---|
| 124 | | - unsigned int tx_dbc_interval; |
|---|
| 125 | | - /* quirk: indicate the value of dbc field in a first packet. */ |
|---|
| 126 | | - unsigned int tx_first_dbc; |
|---|
| 127 | 159 | |
|---|
| 128 | 160 | /* Internal flags. */ |
|---|
| 129 | 161 | enum cip_sfc sfc; |
|---|
| 130 | 162 | unsigned int syt_interval; |
|---|
| 131 | | - unsigned int transfer_delay; |
|---|
| 132 | | - unsigned int data_block_state; |
|---|
| 133 | | - unsigned int last_syt_offset; |
|---|
| 134 | | - unsigned int syt_offset_state; |
|---|
| 135 | 163 | |
|---|
| 136 | 164 | /* For a PCM substream processing. */ |
|---|
| 137 | 165 | struct snd_pcm_substream *pcm; |
|---|
| 138 | | - struct tasklet_struct period_tasklet; |
|---|
| 166 | + struct work_struct period_work; |
|---|
| 139 | 167 | snd_pcm_uframes_t pcm_buffer_pointer; |
|---|
| 140 | 168 | unsigned int pcm_period_pointer; |
|---|
| 141 | 169 | |
|---|
| .. | .. |
|---|
| 146 | 174 | |
|---|
| 147 | 175 | /* For backends to process data blocks. */ |
|---|
| 148 | 176 | void *protocol; |
|---|
| 149 | | - amdtp_stream_process_data_blocks_t process_data_blocks; |
|---|
| 177 | + amdtp_stream_process_ctx_payloads_t process_ctx_payloads; |
|---|
| 178 | + |
|---|
| 179 | + // For domain. |
|---|
| 180 | + int channel; |
|---|
| 181 | + int speed; |
|---|
| 182 | + struct list_head list; |
|---|
| 183 | + struct amdtp_domain *domain; |
|---|
| 150 | 184 | }; |
|---|
| 151 | 185 | |
|---|
| 152 | 186 | int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, |
|---|
| 153 | 187 | enum amdtp_stream_direction dir, enum cip_flags flags, |
|---|
| 154 | 188 | unsigned int fmt, |
|---|
| 155 | | - amdtp_stream_process_data_blocks_t process_data_blocks, |
|---|
| 189 | + amdtp_stream_process_ctx_payloads_t process_ctx_payloads, |
|---|
| 156 | 190 | unsigned int protocol_size); |
|---|
| 157 | 191 | void amdtp_stream_destroy(struct amdtp_stream *s); |
|---|
| 158 | 192 | |
|---|
| .. | .. |
|---|
| 160 | 194 | unsigned int data_block_quadlets); |
|---|
| 161 | 195 | unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s); |
|---|
| 162 | 196 | |
|---|
| 163 | | -int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed); |
|---|
| 164 | 197 | void amdtp_stream_update(struct amdtp_stream *s); |
|---|
| 165 | | -void amdtp_stream_stop(struct amdtp_stream *s); |
|---|
| 166 | 198 | |
|---|
| 167 | 199 | int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, |
|---|
| 168 | 200 | struct snd_pcm_runtime *runtime); |
|---|
| 169 | 201 | |
|---|
| 170 | 202 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s); |
|---|
| 171 | | -unsigned long amdtp_stream_pcm_pointer(struct amdtp_stream *s); |
|---|
| 172 | | -int amdtp_stream_pcm_ack(struct amdtp_stream *s); |
|---|
| 173 | 203 | void amdtp_stream_pcm_abort(struct amdtp_stream *s); |
|---|
| 174 | 204 | |
|---|
| 175 | 205 | extern const unsigned int amdtp_syt_intervals[CIP_SFC_COUNT]; |
|---|
| .. | .. |
|---|
| 244 | 274 | msecs_to_jiffies(timeout)) > 0; |
|---|
| 245 | 275 | } |
|---|
| 246 | 276 | |
|---|
| 277 | +struct seq_desc { |
|---|
| 278 | + unsigned int syt_offset; |
|---|
| 279 | + unsigned int data_blocks; |
|---|
| 280 | +}; |
|---|
| 281 | + |
|---|
| 282 | +struct amdtp_domain { |
|---|
| 283 | + struct list_head streams; |
|---|
| 284 | + |
|---|
| 285 | + unsigned int events_per_period; |
|---|
| 286 | + unsigned int events_per_buffer; |
|---|
| 287 | + |
|---|
| 288 | + struct amdtp_stream *irq_target; |
|---|
| 289 | + |
|---|
| 290 | + struct seq_desc *seq_descs; |
|---|
| 291 | + unsigned int seq_size; |
|---|
| 292 | + unsigned int seq_tail; |
|---|
| 293 | + |
|---|
| 294 | + unsigned int data_block_state; |
|---|
| 295 | + unsigned int syt_offset_state; |
|---|
| 296 | + unsigned int last_syt_offset; |
|---|
| 297 | +}; |
|---|
| 298 | + |
|---|
| 299 | +int amdtp_domain_init(struct amdtp_domain *d); |
|---|
| 300 | +void amdtp_domain_destroy(struct amdtp_domain *d); |
|---|
| 301 | + |
|---|
| 302 | +int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s, |
|---|
| 303 | + int channel, int speed); |
|---|
| 304 | + |
|---|
| 305 | +int amdtp_domain_start(struct amdtp_domain *d, unsigned int ir_delay_cycle); |
|---|
| 306 | +void amdtp_domain_stop(struct amdtp_domain *d); |
|---|
| 307 | + |
|---|
| 308 | +static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d, |
|---|
| 309 | + unsigned int events_per_period, |
|---|
| 310 | + unsigned int events_per_buffer) |
|---|
| 311 | +{ |
|---|
| 312 | + d->events_per_period = events_per_period; |
|---|
| 313 | + d->events_per_buffer = events_per_buffer; |
|---|
| 314 | + |
|---|
| 315 | + return 0; |
|---|
| 316 | +} |
|---|
| 317 | + |
|---|
| 318 | +unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, |
|---|
| 319 | + struct amdtp_stream *s); |
|---|
| 320 | +int amdtp_domain_stream_pcm_ack(struct amdtp_domain *d, struct amdtp_stream *s); |
|---|
| 321 | + |
|---|
| 247 | 322 | #endif |
|---|