aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/speakers.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/speakers.c')
-rw-r--r--sound/firewire/speakers.c100
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
188static void fwspk_stop_stream(struct fwspk *fwspk) 182static 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
196static 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
226error:
227 kfree(buf);
228
229 return err;
230}
231
232static int fwspk_hw_params(struct snd_pcm_substream *substream, 190static 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
341static int fwspk_create_pcm(struct fwspk *fwspk) 302static 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
746static void fwspk_remove(struct fw_unit *unit) 708static 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);