.. | .. |
---|
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 |
---|