diff options
Diffstat (limited to 'sound/firewire/speakers.c')
-rw-r--r-- | sound/firewire/speakers.c | 100 |
1 files changed, 31 insertions, 69 deletions
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 9f7ef219b109..768d40ddfebb 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c | |||
@@ -51,7 +51,7 @@ struct fwspk { | |||
51 | const struct device_info *device_info; | 51 | const struct device_info *device_info; |
52 | struct mutex mutex; | 52 | struct mutex mutex; |
53 | struct cmp_connection connection; | 53 | struct cmp_connection connection; |
54 | struct amdtp_out_stream stream; | 54 | struct amdtp_stream stream; |
55 | bool mute; | 55 | bool mute; |
56 | s16 volume[6]; | 56 | s16 volume[6]; |
57 | s16 volume_min; | 57 | s16 volume_min; |
@@ -167,13 +167,7 @@ static int fwspk_open(struct snd_pcm_substream *substream) | |||
167 | if (err < 0) | 167 | if (err < 0) |
168 | return err; | 168 | return err; |
169 | 169 | ||
170 | err = snd_pcm_hw_constraint_minmax(runtime, | 170 | err = amdtp_stream_add_pcm_hw_constraints(&fwspk->stream, runtime); |
171 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
172 | 5000, UINT_MAX); | ||
173 | if (err < 0) | ||
174 | return err; | ||
175 | |||
176 | err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | ||
177 | if (err < 0) | 171 | if (err < 0) |
178 | return err; | 172 | return err; |
179 | 173 | ||
@@ -187,48 +181,12 @@ static int fwspk_close(struct snd_pcm_substream *substream) | |||
187 | 181 | ||
188 | static void fwspk_stop_stream(struct fwspk *fwspk) | 182 | static void fwspk_stop_stream(struct fwspk *fwspk) |
189 | { | 183 | { |
190 | if (amdtp_out_stream_running(&fwspk->stream)) { | 184 | if (amdtp_stream_running(&fwspk->stream)) { |
191 | amdtp_out_stream_stop(&fwspk->stream); | 185 | amdtp_stream_stop(&fwspk->stream); |
192 | cmp_connection_break(&fwspk->connection); | 186 | cmp_connection_break(&fwspk->connection); |
193 | } | 187 | } |
194 | } | 188 | } |
195 | 189 | ||
196 | static int fwspk_set_rate(struct fwspk *fwspk, unsigned int sfc) | ||
197 | { | ||
198 | u8 *buf; | ||
199 | int err; | ||
200 | |||
201 | buf = kmalloc(8, GFP_KERNEL); | ||
202 | if (!buf) | ||
203 | return -ENOMEM; | ||
204 | |||
205 | buf[0] = 0x00; /* AV/C, CONTROL */ | ||
206 | buf[1] = 0xff; /* unit */ | ||
207 | buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */ | ||
208 | buf[3] = 0x00; /* plug 0 */ | ||
209 | buf[4] = 0x90; /* format: audio */ | ||
210 | buf[5] = 0x00 | sfc; /* AM824, frequency */ | ||
211 | buf[6] = 0xff; /* SYT (not used) */ | ||
212 | buf[7] = 0xff; | ||
213 | |||
214 | err = fcp_avc_transaction(fwspk->unit, buf, 8, buf, 8, | ||
215 | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); | ||
216 | if (err < 0) | ||
217 | goto error; | ||
218 | if (err < 6 || buf[0] != 0x09 /* ACCEPTED */) { | ||
219 | dev_err(&fwspk->unit->device, "failed to set sample rate\n"); | ||
220 | err = -EIO; | ||
221 | goto error; | ||
222 | } | ||
223 | |||
224 | err = 0; | ||
225 | |||
226 | error: | ||
227 | kfree(buf); | ||
228 | |||
229 | return err; | ||
230 | } | ||
231 | |||
232 | static int fwspk_hw_params(struct snd_pcm_substream *substream, | 190 | static int fwspk_hw_params(struct snd_pcm_substream *substream, |
233 | struct snd_pcm_hw_params *hw_params) | 191 | struct snd_pcm_hw_params *hw_params) |
234 | { | 192 | { |
@@ -244,17 +202,20 @@ static int fwspk_hw_params(struct snd_pcm_substream *substream, | |||
244 | if (err < 0) | 202 | if (err < 0) |
245 | goto error; | 203 | goto error; |
246 | 204 | ||
247 | amdtp_out_stream_set_parameters(&fwspk->stream, | 205 | amdtp_stream_set_parameters(&fwspk->stream, |
248 | params_rate(hw_params), | 206 | params_rate(hw_params), |
249 | params_channels(hw_params), | 207 | params_channels(hw_params), |
250 | 0); | 208 | 0); |
251 | 209 | ||
252 | amdtp_out_stream_set_pcm_format(&fwspk->stream, | 210 | amdtp_stream_set_pcm_format(&fwspk->stream, |
253 | params_format(hw_params)); | 211 | params_format(hw_params)); |
254 | 212 | ||
255 | err = fwspk_set_rate(fwspk, fwspk->stream.sfc); | 213 | err = avc_general_set_sig_fmt(fwspk->unit, params_rate(hw_params), |
256 | if (err < 0) | 214 | AVC_GENERAL_PLUG_DIR_IN, 0); |
215 | if (err < 0) { | ||
216 | dev_err(&fwspk->unit->device, "failed to set sample rate\n"); | ||
257 | goto err_buffer; | 217 | goto err_buffer; |
218 | } | ||
258 | 219 | ||
259 | return 0; | 220 | return 0; |
260 | 221 | ||
@@ -282,25 +243,25 @@ static int fwspk_prepare(struct snd_pcm_substream *substream) | |||
282 | 243 | ||
283 | mutex_lock(&fwspk->mutex); | 244 | mutex_lock(&fwspk->mutex); |
284 | 245 | ||
285 | if (amdtp_out_streaming_error(&fwspk->stream)) | 246 | if (amdtp_streaming_error(&fwspk->stream)) |
286 | fwspk_stop_stream(fwspk); | 247 | fwspk_stop_stream(fwspk); |
287 | 248 | ||
288 | if (!amdtp_out_stream_running(&fwspk->stream)) { | 249 | if (!amdtp_stream_running(&fwspk->stream)) { |
289 | err = cmp_connection_establish(&fwspk->connection, | 250 | err = cmp_connection_establish(&fwspk->connection, |
290 | amdtp_out_stream_get_max_payload(&fwspk->stream)); | 251 | amdtp_stream_get_max_payload(&fwspk->stream)); |
291 | if (err < 0) | 252 | if (err < 0) |
292 | goto err_mutex; | 253 | goto err_mutex; |
293 | 254 | ||
294 | err = amdtp_out_stream_start(&fwspk->stream, | 255 | err = amdtp_stream_start(&fwspk->stream, |
295 | fwspk->connection.resources.channel, | 256 | fwspk->connection.resources.channel, |
296 | fwspk->connection.speed); | 257 | fwspk->connection.speed); |
297 | if (err < 0) | 258 | if (err < 0) |
298 | goto err_connection; | 259 | goto err_connection; |
299 | } | 260 | } |
300 | 261 | ||
301 | mutex_unlock(&fwspk->mutex); | 262 | mutex_unlock(&fwspk->mutex); |
302 | 263 | ||
303 | amdtp_out_stream_pcm_prepare(&fwspk->stream); | 264 | amdtp_stream_pcm_prepare(&fwspk->stream); |
304 | 265 | ||
305 | return 0; | 266 | return 0; |
306 | 267 | ||
@@ -327,7 +288,7 @@ static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd) | |||
327 | default: | 288 | default: |
328 | return -EINVAL; | 289 | return -EINVAL; |
329 | } | 290 | } |
330 | amdtp_out_stream_pcm_trigger(&fwspk->stream, pcm); | 291 | amdtp_stream_pcm_trigger(&fwspk->stream, pcm); |
331 | return 0; | 292 | return 0; |
332 | } | 293 | } |
333 | 294 | ||
@@ -335,7 +296,7 @@ static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream) | |||
335 | { | 296 | { |
336 | struct fwspk *fwspk = substream->private_data; | 297 | struct fwspk *fwspk = substream->private_data; |
337 | 298 | ||
338 | return amdtp_out_stream_pcm_pointer(&fwspk->stream); | 299 | return amdtp_stream_pcm_pointer(&fwspk->stream); |
339 | } | 300 | } |
340 | 301 | ||
341 | static int fwspk_create_pcm(struct fwspk *fwspk) | 302 | static int fwspk_create_pcm(struct fwspk *fwspk) |
@@ -653,7 +614,7 @@ static void fwspk_card_free(struct snd_card *card) | |||
653 | { | 614 | { |
654 | struct fwspk *fwspk = card->private_data; | 615 | struct fwspk *fwspk = card->private_data; |
655 | 616 | ||
656 | amdtp_out_stream_destroy(&fwspk->stream); | 617 | amdtp_stream_destroy(&fwspk->stream); |
657 | cmp_connection_destroy(&fwspk->connection); | 618 | cmp_connection_destroy(&fwspk->connection); |
658 | fw_unit_put(fwspk->unit); | 619 | fw_unit_put(fwspk->unit); |
659 | mutex_destroy(&fwspk->mutex); | 620 | mutex_destroy(&fwspk->mutex); |
@@ -679,11 +640,12 @@ static int fwspk_probe(struct fw_unit *unit, | |||
679 | fwspk->unit = fw_unit_get(unit); | 640 | fwspk->unit = fw_unit_get(unit); |
680 | fwspk->device_info = (const struct device_info *)id->driver_data; | 641 | fwspk->device_info = (const struct device_info *)id->driver_data; |
681 | 642 | ||
682 | err = cmp_connection_init(&fwspk->connection, unit, 0); | 643 | err = cmp_connection_init(&fwspk->connection, unit, CMP_INPUT, 0); |
683 | if (err < 0) | 644 | if (err < 0) |
684 | goto err_unit; | 645 | goto err_unit; |
685 | 646 | ||
686 | err = amdtp_out_stream_init(&fwspk->stream, unit, CIP_NONBLOCKING); | 647 | err = amdtp_stream_init(&fwspk->stream, unit, AMDTP_OUT_STREAM, |
648 | CIP_NONBLOCKING); | ||
687 | if (err < 0) | 649 | if (err < 0) |
688 | goto err_connection; | 650 | goto err_connection; |
689 | 651 | ||
@@ -733,21 +695,21 @@ static void fwspk_bus_reset(struct fw_unit *unit) | |||
733 | fcp_bus_reset(fwspk->unit); | 695 | fcp_bus_reset(fwspk->unit); |
734 | 696 | ||
735 | if (cmp_connection_update(&fwspk->connection) < 0) { | 697 | if (cmp_connection_update(&fwspk->connection) < 0) { |
736 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 698 | amdtp_stream_pcm_abort(&fwspk->stream); |
737 | mutex_lock(&fwspk->mutex); | 699 | mutex_lock(&fwspk->mutex); |
738 | fwspk_stop_stream(fwspk); | 700 | fwspk_stop_stream(fwspk); |
739 | mutex_unlock(&fwspk->mutex); | 701 | mutex_unlock(&fwspk->mutex); |
740 | return; | 702 | return; |
741 | } | 703 | } |
742 | 704 | ||
743 | amdtp_out_stream_update(&fwspk->stream); | 705 | amdtp_stream_update(&fwspk->stream); |
744 | } | 706 | } |
745 | 707 | ||
746 | static void fwspk_remove(struct fw_unit *unit) | 708 | static void fwspk_remove(struct fw_unit *unit) |
747 | { | 709 | { |
748 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); | 710 | struct fwspk *fwspk = dev_get_drvdata(&unit->device); |
749 | 711 | ||
750 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 712 | amdtp_stream_pcm_abort(&fwspk->stream); |
751 | snd_card_disconnect(fwspk->card); | 713 | snd_card_disconnect(fwspk->card); |
752 | 714 | ||
753 | mutex_lock(&fwspk->mutex); | 715 | mutex_lock(&fwspk->mutex); |