diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 12:10:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-03 12:10:23 -0400 |
commit | 9992ba72327fa0d8bdc9fb624e80f5cce338a711 (patch) | |
tree | e0bf31ae53cb19c44674df7e0d0343a26037ad34 /sound | |
parent | 00fdffb5131125dce0702bf61e24a806ec3aed80 (diff) | |
parent | 4ca231b2e6ed171107c5b21f9e92d1965fd6fd9e (diff) |
Merge tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"Mostly many small changes spread as seen in diffstat in sound/*
directory by this update. A significant change in the subsystem level
is the introduction of snd_soc_component, which will help more generic
handling of SoC and off-SoC components.
Also, snd_BUG_ON() macro is enabled unconditionally now due to its
misuses, so people might hit kernel warnings (it's a good thing for
us).
- compress-offload: support for capture by Charles Keepax
- HD-audio: codec delay support by Dylan Reid
- HD-audio: improvements/fixes in generic parser: better headphone
mic and headset mic support, jack_modes hint consolidation, proper
beep attach/detachment, generalized power filter controls by David
Henningsson, et al
- HD-audio: Improved management of HDMI codec pins/converters
- HD-audio: Better pin/DAC assignment for VIA codecs
- HD-audio: Haswell HDMI workarounds
- HD-audio: ALC268 codec support, a few new quirks for Chromebooks
- USB: regression fixes: USB-MIDI autopm fix, the recent ISO latency
fix by Clemens Ladisch
- USB: support for DSD formats by Daniel Mack
- USB: A few UAC2 device endian/cock fixes by Eldad Zack
- USB: quirks for Emu 192kHz support, Novation Twitch DJ controller,
Yamaha THRxx devices
- HDSPM: updates for TCO controls by Adrian Knoth
- ASoC: Add a snd_soc_component object type for generic handling of
SoC and off-SoC components by Kuninori Morimoto,
- dmaengine: a large set of cleanups and conversions by Lars-Peter
Clausen
- ASoC DAPM: performance optimizations from Ryo Tsutsui
- ASoC DAPM: support for mixer control sharing by Stephen Warren
- ASoC: multiplatform ARM cleanups from Arnd Bergmann
- ASoC: new codec drivers for AK5385 and TAS5086 from Daniel Mack"
* tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (315 commits)
ALSA: usb-audio: caiaq: fix endianness bug in snd_usb_caiaq_maschine_dispatch
ALSA: asihpi: add format support check in snd_card_asihpi_capture_formats
ALSA: pcm_format_to_bits strong-typed conversion
ALSA: compress: fix the states to check for allowing read
ALSA: hda - Move Thinkpad X220 to use auto parser
ALSA: USB: adjust for changed 3.8 USB API
ALSA: usb - Avoid unnecessary sample rate changes on USB 2.0 clock sources
sound: oss/dmabuf: use dma_map_single
ALSA: ali5451: use mdelay instead of large udelay constants
ALSA: hda - Add the support for ALC286 codec
ALSA: usb-audio: USB quirk for Yamaha THR10C
ALSA: usb-audio: USB quirk for Yamaha THR5A
ALSA: usb-audio: USB quirk for Yamaha THR10
ALSA: usb-audio: Fix autopm error during probing
ALSA: snd-usb: try harder to find USB_DT_CS_ENDPOINT
ALSA: sound kconfig typo
ALSA: emu10k1: Fix dock firmware loading
ASoC: ux500: forward declare msp_i2s_platform_data
ASoC: davinci-mcasp: Add Support BCLK-to-LRCLK ratio for TDM modes
ASoC: davinci-pcm, davinci-mcasp: Clean up active_serializers
...
Diffstat (limited to 'sound')
241 files changed, 7059 insertions, 3622 deletions
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 19491ed9292f..7b74a4ba75f8 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c | |||
@@ -179,7 +179,7 @@ static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in) | |||
179 | */ | 179 | */ |
180 | if (other->active) { | 180 | if (other->active) { |
181 | /* FIXME: is this guaranteed by the alsa api? */ | 181 | /* FIXME: is this guaranteed by the alsa api? */ |
182 | hw->formats &= (1ULL << i2sdev->format); | 182 | hw->formats &= pcm_format_to_bits(i2sdev->format); |
183 | /* see above, restrict rates to the one we already have */ | 183 | /* see above, restrict rates to the one we already have */ |
184 | hw->rate_min = i2sdev->rate; | 184 | hw->rate_min = i2sdev->rate; |
185 | hw->rate_max = i2sdev->rate; | 185 | hw->rate_max = i2sdev->rate; |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 79d6bda58753..6b7e2b5a72de 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -182,7 +182,7 @@ static int atmel_ac97c_playback_open(struct snd_pcm_substream *substream) | |||
182 | runtime->hw.rate_max = chip->cur_rate; | 182 | runtime->hw.rate_max = chip->cur_rate; |
183 | } | 183 | } |
184 | if (chip->cur_format) | 184 | if (chip->cur_format) |
185 | runtime->hw.formats = (1ULL << chip->cur_format); | 185 | runtime->hw.formats = pcm_format_to_bits(chip->cur_format); |
186 | mutex_unlock(&opened_mutex); | 186 | mutex_unlock(&opened_mutex); |
187 | chip->playback_substream = substream; | 187 | chip->playback_substream = substream; |
188 | return 0; | 188 | return 0; |
@@ -201,7 +201,7 @@ static int atmel_ac97c_capture_open(struct snd_pcm_substream *substream) | |||
201 | runtime->hw.rate_max = chip->cur_rate; | 201 | runtime->hw.rate_max = chip->cur_rate; |
202 | } | 202 | } |
203 | if (chip->cur_format) | 203 | if (chip->cur_format) |
204 | runtime->hw.formats = (1ULL << chip->cur_format); | 204 | runtime->hw.formats = pcm_format_to_bits(chip->cur_format); |
205 | mutex_unlock(&opened_mutex); | 205 | mutex_unlock(&opened_mutex); |
206 | chip->capture_substream = substream; | 206 | chip->capture_substream = substream; |
207 | return 0; | 207 | return 0; |
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index c84abc886e90..99db892d7299 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
@@ -28,11 +28,13 @@ | |||
28 | #include <linux/file.h> | 28 | #include <linux/file.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/math64.h> | ||
31 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
32 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
33 | #include <linux/poll.h> | 34 | #include <linux/poll.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/types.h> | ||
36 | #include <linux/uio.h> | 38 | #include <linux/uio.h> |
37 | #include <linux/uaccess.h> | 39 | #include <linux/uaccess.h> |
38 | #include <linux/module.h> | 40 | #include <linux/module.h> |
@@ -152,26 +154,23 @@ static int snd_compr_update_tstamp(struct snd_compr_stream *stream, | |||
152 | stream->ops->pointer(stream, tstamp); | 154 | stream->ops->pointer(stream, tstamp); |
153 | pr_debug("dsp consumed till %d total %d bytes\n", | 155 | pr_debug("dsp consumed till %d total %d bytes\n", |
154 | tstamp->byte_offset, tstamp->copied_total); | 156 | tstamp->byte_offset, tstamp->copied_total); |
155 | stream->runtime->hw_pointer = tstamp->byte_offset; | 157 | if (stream->direction == SND_COMPRESS_PLAYBACK) |
156 | stream->runtime->total_bytes_transferred = tstamp->copied_total; | 158 | stream->runtime->total_bytes_transferred = tstamp->copied_total; |
159 | else | ||
160 | stream->runtime->total_bytes_available = tstamp->copied_total; | ||
157 | return 0; | 161 | return 0; |
158 | } | 162 | } |
159 | 163 | ||
160 | static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, | 164 | static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, |
161 | struct snd_compr_avail *avail) | 165 | struct snd_compr_avail *avail) |
162 | { | 166 | { |
163 | long avail_calc; /*this needs to be signed variable */ | ||
164 | |||
165 | memset(avail, 0, sizeof(*avail)); | 167 | memset(avail, 0, sizeof(*avail)); |
166 | snd_compr_update_tstamp(stream, &avail->tstamp); | 168 | snd_compr_update_tstamp(stream, &avail->tstamp); |
167 | /* Still need to return avail even if tstamp can't be filled in */ | 169 | /* Still need to return avail even if tstamp can't be filled in */ |
168 | 170 | ||
169 | /* FIXME: This needs to be different for capture stream, | ||
170 | available is # of compressed data, for playback it's | ||
171 | remainder of buffer */ | ||
172 | |||
173 | if (stream->runtime->total_bytes_available == 0 && | 171 | if (stream->runtime->total_bytes_available == 0 && |
174 | stream->runtime->state == SNDRV_PCM_STATE_SETUP) { | 172 | stream->runtime->state == SNDRV_PCM_STATE_SETUP && |
173 | stream->direction == SND_COMPRESS_PLAYBACK) { | ||
175 | pr_debug("detected init and someone forgot to do a write\n"); | 174 | pr_debug("detected init and someone forgot to do a write\n"); |
176 | return stream->runtime->buffer_size; | 175 | return stream->runtime->buffer_size; |
177 | } | 176 | } |
@@ -180,26 +179,22 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, | |||
180 | stream->runtime->total_bytes_transferred); | 179 | stream->runtime->total_bytes_transferred); |
181 | if (stream->runtime->total_bytes_available == | 180 | if (stream->runtime->total_bytes_available == |
182 | stream->runtime->total_bytes_transferred) { | 181 | stream->runtime->total_bytes_transferred) { |
183 | pr_debug("both pointers are same, returning full avail\n"); | 182 | if (stream->direction == SND_COMPRESS_PLAYBACK) { |
184 | return stream->runtime->buffer_size; | 183 | pr_debug("both pointers are same, returning full avail\n"); |
184 | return stream->runtime->buffer_size; | ||
185 | } else { | ||
186 | pr_debug("both pointers are same, returning no avail\n"); | ||
187 | return 0; | ||
188 | } | ||
185 | } | 189 | } |
186 | 190 | ||
187 | /* FIXME: this routine isn't consistent, in one test we use | 191 | avail->avail = stream->runtime->total_bytes_available - |
188 | * cumulative values and in the other byte offsets. Do we | 192 | stream->runtime->total_bytes_transferred; |
189 | * really need the byte offsets if the cumulative values have | 193 | if (stream->direction == SND_COMPRESS_PLAYBACK) |
190 | * been updated? In the PCM interface app_ptr and hw_ptr are | 194 | avail->avail = stream->runtime->buffer_size - avail->avail; |
191 | * already cumulative */ | ||
192 | 195 | ||
193 | avail_calc = stream->runtime->buffer_size - | 196 | pr_debug("ret avail as %lld\n", avail->avail); |
194 | (stream->runtime->app_pointer - stream->runtime->hw_pointer); | 197 | return avail->avail; |
195 | pr_debug("calc avail as %ld, app_ptr %lld, hw+ptr %lld\n", avail_calc, | ||
196 | stream->runtime->app_pointer, | ||
197 | stream->runtime->hw_pointer); | ||
198 | if (avail_calc >= stream->runtime->buffer_size) | ||
199 | avail_calc -= stream->runtime->buffer_size; | ||
200 | pr_debug("ret avail as %ld\n", avail_calc); | ||
201 | avail->avail = avail_calc; | ||
202 | return avail_calc; | ||
203 | } | 198 | } |
204 | 199 | ||
205 | static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) | 200 | static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) |
@@ -230,21 +225,24 @@ static int snd_compr_write_data(struct snd_compr_stream *stream, | |||
230 | void *dstn; | 225 | void *dstn; |
231 | size_t copy; | 226 | size_t copy; |
232 | struct snd_compr_runtime *runtime = stream->runtime; | 227 | struct snd_compr_runtime *runtime = stream->runtime; |
228 | /* 64-bit Modulus */ | ||
229 | u64 app_pointer = div64_u64(runtime->total_bytes_available, | ||
230 | runtime->buffer_size); | ||
231 | app_pointer = runtime->total_bytes_available - | ||
232 | (app_pointer * runtime->buffer_size); | ||
233 | 233 | ||
234 | dstn = runtime->buffer + runtime->app_pointer; | 234 | dstn = runtime->buffer + app_pointer; |
235 | pr_debug("copying %ld at %lld\n", | 235 | pr_debug("copying %ld at %lld\n", |
236 | (unsigned long)count, runtime->app_pointer); | 236 | (unsigned long)count, app_pointer); |
237 | if (count < runtime->buffer_size - runtime->app_pointer) { | 237 | if (count < runtime->buffer_size - app_pointer) { |
238 | if (copy_from_user(dstn, buf, count)) | 238 | if (copy_from_user(dstn, buf, count)) |
239 | return -EFAULT; | 239 | return -EFAULT; |
240 | runtime->app_pointer += count; | ||
241 | } else { | 240 | } else { |
242 | copy = runtime->buffer_size - runtime->app_pointer; | 241 | copy = runtime->buffer_size - app_pointer; |
243 | if (copy_from_user(dstn, buf, copy)) | 242 | if (copy_from_user(dstn, buf, copy)) |
244 | return -EFAULT; | 243 | return -EFAULT; |
245 | if (copy_from_user(runtime->buffer, buf + copy, count - copy)) | 244 | if (copy_from_user(runtime->buffer, buf + copy, count - copy)) |
246 | return -EFAULT; | 245 | return -EFAULT; |
247 | runtime->app_pointer = count - copy; | ||
248 | } | 246 | } |
249 | /* if DSP cares, let it know data has been written */ | 247 | /* if DSP cares, let it know data has been written */ |
250 | if (stream->ops->ack) | 248 | if (stream->ops->ack) |
@@ -278,10 +276,12 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, | |||
278 | if (avail > count) | 276 | if (avail > count) |
279 | avail = count; | 277 | avail = count; |
280 | 278 | ||
281 | if (stream->ops->copy) | 279 | if (stream->ops->copy) { |
282 | retval = stream->ops->copy(stream, buf, avail); | 280 | char __user* cbuf = (char __user*)buf; |
283 | else | 281 | retval = stream->ops->copy(stream, cbuf, avail); |
282 | } else { | ||
284 | retval = snd_compr_write_data(stream, buf, avail); | 283 | retval = snd_compr_write_data(stream, buf, avail); |
284 | } | ||
285 | if (retval > 0) | 285 | if (retval > 0) |
286 | stream->runtime->total_bytes_available += retval; | 286 | stream->runtime->total_bytes_available += retval; |
287 | 287 | ||
@@ -300,7 +300,49 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, | |||
300 | static ssize_t snd_compr_read(struct file *f, char __user *buf, | 300 | static ssize_t snd_compr_read(struct file *f, char __user *buf, |
301 | size_t count, loff_t *offset) | 301 | size_t count, loff_t *offset) |
302 | { | 302 | { |
303 | return -ENXIO; | 303 | struct snd_compr_file *data = f->private_data; |
304 | struct snd_compr_stream *stream; | ||
305 | size_t avail; | ||
306 | int retval; | ||
307 | |||
308 | if (snd_BUG_ON(!data)) | ||
309 | return -EFAULT; | ||
310 | |||
311 | stream = &data->stream; | ||
312 | mutex_lock(&stream->device->lock); | ||
313 | |||
314 | /* read is allowed when stream is running, paused, draining and setup | ||
315 | * (yes setup is state which we transition to after stop, so if user | ||
316 | * wants to read data after stop we allow that) | ||
317 | */ | ||
318 | switch (stream->runtime->state) { | ||
319 | case SNDRV_PCM_STATE_OPEN: | ||
320 | case SNDRV_PCM_STATE_PREPARED: | ||
321 | case SNDRV_PCM_STATE_XRUN: | ||
322 | case SNDRV_PCM_STATE_SUSPENDED: | ||
323 | case SNDRV_PCM_STATE_DISCONNECTED: | ||
324 | retval = -EBADFD; | ||
325 | goto out; | ||
326 | } | ||
327 | |||
328 | avail = snd_compr_get_avail(stream); | ||
329 | pr_debug("avail returned %ld\n", (unsigned long)avail); | ||
330 | /* calculate how much we can read from buffer */ | ||
331 | if (avail > count) | ||
332 | avail = count; | ||
333 | |||
334 | if (stream->ops->copy) { | ||
335 | retval = stream->ops->copy(stream, buf, avail); | ||
336 | } else { | ||
337 | retval = -ENXIO; | ||
338 | goto out; | ||
339 | } | ||
340 | if (retval > 0) | ||
341 | stream->runtime->total_bytes_transferred += retval; | ||
342 | |||
343 | out: | ||
344 | mutex_unlock(&stream->device->lock); | ||
345 | return retval; | ||
304 | } | 346 | } |
305 | 347 | ||
306 | static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma) | 348 | static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma) |
@@ -375,6 +417,7 @@ snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg) | |||
375 | if (!stream->ops->get_caps) | 417 | if (!stream->ops->get_caps) |
376 | return -ENXIO; | 418 | return -ENXIO; |
377 | 419 | ||
420 | memset(&caps, 0, sizeof(caps)); | ||
378 | retval = stream->ops->get_caps(stream, &caps); | 421 | retval = stream->ops->get_caps(stream, &caps); |
379 | if (retval) | 422 | if (retval) |
380 | goto out; | 423 | goto out; |
@@ -393,7 +436,7 @@ snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) | |||
393 | if (!stream->ops->get_codec_caps) | 436 | if (!stream->ops->get_codec_caps) |
394 | return -ENXIO; | 437 | return -ENXIO; |
395 | 438 | ||
396 | caps = kmalloc(sizeof(*caps), GFP_KERNEL); | 439 | caps = kzalloc(sizeof(*caps), GFP_KERNEL); |
397 | if (!caps) | 440 | if (!caps) |
398 | return -ENOMEM; | 441 | return -ENOMEM; |
399 | 442 | ||
@@ -485,9 +528,14 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) | |||
485 | retval = stream->ops->set_params(stream, params); | 528 | retval = stream->ops->set_params(stream, params); |
486 | if (retval) | 529 | if (retval) |
487 | goto out; | 530 | goto out; |
488 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | 531 | |
489 | stream->metadata_set = false; | 532 | stream->metadata_set = false; |
490 | stream->next_track = false; | 533 | stream->next_track = false; |
534 | |||
535 | if (stream->direction == SND_COMPRESS_PLAYBACK) | ||
536 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | ||
537 | else | ||
538 | stream->runtime->state = SNDRV_PCM_STATE_PREPARED; | ||
491 | } else { | 539 | } else { |
492 | return -EPERM; | 540 | return -EPERM; |
493 | } | 541 | } |
@@ -505,7 +553,7 @@ snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) | |||
505 | if (!stream->ops->get_params) | 553 | if (!stream->ops->get_params) |
506 | return -EBADFD; | 554 | return -EBADFD; |
507 | 555 | ||
508 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 556 | params = kzalloc(sizeof(*params), GFP_KERNEL); |
509 | if (!params) | 557 | if (!params) |
510 | return -ENOMEM; | 558 | return -ENOMEM; |
511 | retval = stream->ops->get_params(stream, params); | 559 | retval = stream->ops->get_params(stream, params); |
@@ -622,8 +670,6 @@ static int snd_compr_stop(struct snd_compr_stream *stream) | |||
622 | if (!retval) { | 670 | if (!retval) { |
623 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | 671 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; |
624 | wake_up(&stream->runtime->sleep); | 672 | wake_up(&stream->runtime->sleep); |
625 | stream->runtime->hw_pointer = 0; | ||
626 | stream->runtime->app_pointer = 0; | ||
627 | stream->runtime->total_bytes_available = 0; | 673 | stream->runtime->total_bytes_available = 0; |
628 | stream->runtime->total_bytes_transferred = 0; | 674 | stream->runtime->total_bytes_transferred = 0; |
629 | } | 675 | } |
diff --git a/sound/core/control.c b/sound/core/control.c index 8c7c2c9bba61..d8aa206e8bde 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -190,7 +190,7 @@ EXPORT_SYMBOL(snd_ctl_notify); | |||
190 | * Allocates a new struct snd_kcontrol instance and copies the given template | 190 | * Allocates a new struct snd_kcontrol instance and copies the given template |
191 | * to the new instance. It does not copy volatile data (access). | 191 | * to the new instance. It does not copy volatile data (access). |
192 | * | 192 | * |
193 | * Returns the pointer of the new instance, or NULL on failure. | 193 | * Return: The pointer of the new instance, or %NULL on failure. |
194 | */ | 194 | */ |
195 | static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, | 195 | static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, |
196 | unsigned int access) | 196 | unsigned int access) |
@@ -224,7 +224,7 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, | |||
224 | * template. When the access field of ncontrol is 0, it's assumed as | 224 | * template. When the access field of ncontrol is 0, it's assumed as |
225 | * READWRITE access. When the count field is 0, it's assumes as one. | 225 | * READWRITE access. When the count field is 0, it's assumes as one. |
226 | * | 226 | * |
227 | * Returns the pointer of the newly generated instance, or NULL on failure. | 227 | * Return: The pointer of the newly generated instance, or %NULL on failure. |
228 | */ | 228 | */ |
229 | struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, | 229 | struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, |
230 | void *private_data) | 230 | void *private_data) |
@@ -322,9 +322,10 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) | |||
322 | * snd_ctl_new1() to the given card. Assigns also an unique | 322 | * snd_ctl_new1() to the given card. Assigns also an unique |
323 | * numid used for fast search. | 323 | * numid used for fast search. |
324 | * | 324 | * |
325 | * Returns zero if successful, or a negative error code on failure. | ||
326 | * | ||
327 | * It frees automatically the control which cannot be added. | 325 | * It frees automatically the control which cannot be added. |
326 | * | ||
327 | * Return: Zero if successful, or a negative error code on failure. | ||
328 | * | ||
328 | */ | 329 | */ |
329 | int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | 330 | int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) |
330 | { | 331 | { |
@@ -380,9 +381,9 @@ EXPORT_SYMBOL(snd_ctl_add); | |||
380 | * and the add_on_replace flag is set, the control is added. If the | 381 | * and the add_on_replace flag is set, the control is added. If the |
381 | * control exists, it is destroyed first. | 382 | * control exists, it is destroyed first. |
382 | * | 383 | * |
383 | * Returns zero if successful, or a negative error code on failure. | ||
384 | * | ||
385 | * It frees automatically the control which cannot be added or replaced. | 384 | * It frees automatically the control which cannot be added or replaced. |
385 | * | ||
386 | * Return: Zero if successful, or a negative error code on failure. | ||
386 | */ | 387 | */ |
387 | int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, | 388 | int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, |
388 | bool add_on_replace) | 389 | bool add_on_replace) |
@@ -442,8 +443,8 @@ EXPORT_SYMBOL(snd_ctl_replace); | |||
442 | * Removes the control from the card and then releases the instance. | 443 | * Removes the control from the card and then releases the instance. |
443 | * You don't need to call snd_ctl_free_one(). You must be in | 444 | * You don't need to call snd_ctl_free_one(). You must be in |
444 | * the write lock - down_write(&card->controls_rwsem). | 445 | * the write lock - down_write(&card->controls_rwsem). |
445 | * | 446 | * |
446 | * Returns 0 if successful, or a negative error code on failure. | 447 | * Return: 0 if successful, or a negative error code on failure. |
447 | */ | 448 | */ |
448 | int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) | 449 | int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) |
449 | { | 450 | { |
@@ -470,8 +471,8 @@ EXPORT_SYMBOL(snd_ctl_remove); | |||
470 | * | 471 | * |
471 | * Finds the control instance with the given id, removes it from the | 472 | * Finds the control instance with the given id, removes it from the |
472 | * card list and releases it. | 473 | * card list and releases it. |
473 | * | 474 | * |
474 | * Returns 0 if successful, or a negative error code on failure. | 475 | * Return: 0 if successful, or a negative error code on failure. |
475 | */ | 476 | */ |
476 | int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) | 477 | int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) |
477 | { | 478 | { |
@@ -498,8 +499,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id); | |||
498 | * | 499 | * |
499 | * Finds the control instance with the given id, removes it from the | 500 | * Finds the control instance with the given id, removes it from the |
500 | * card list and releases it. | 501 | * card list and releases it. |
501 | * | 502 | * |
502 | * Returns 0 if successful, or a negative error code on failure. | 503 | * Return: 0 if successful, or a negative error code on failure. |
503 | */ | 504 | */ |
504 | static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, | 505 | static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, |
505 | struct snd_ctl_elem_id *id) | 506 | struct snd_ctl_elem_id *id) |
@@ -541,7 +542,7 @@ error: | |||
541 | * Finds the control instance with the given id, and activate or | 542 | * Finds the control instance with the given id, and activate or |
542 | * inactivate the control together with notification, if changed. | 543 | * inactivate the control together with notification, if changed. |
543 | * | 544 | * |
544 | * Returns 0 if unchanged, 1 if changed, or a negative error code on failure. | 545 | * Return: 0 if unchanged, 1 if changed, or a negative error code on failure. |
545 | */ | 546 | */ |
546 | int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, | 547 | int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, |
547 | int active) | 548 | int active) |
@@ -587,7 +588,7 @@ EXPORT_SYMBOL_GPL(snd_ctl_activate_id); | |||
587 | * Finds the control with the old id from the card, and replaces the | 588 | * Finds the control with the old id from the card, and replaces the |
588 | * id with the new one. | 589 | * id with the new one. |
589 | * | 590 | * |
590 | * Returns zero if successful, or a negative error code on failure. | 591 | * Return: Zero if successful, or a negative error code on failure. |
591 | */ | 592 | */ |
592 | int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, | 593 | int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, |
593 | struct snd_ctl_elem_id *dst_id) | 594 | struct snd_ctl_elem_id *dst_id) |
@@ -616,10 +617,11 @@ EXPORT_SYMBOL(snd_ctl_rename_id); | |||
616 | * | 617 | * |
617 | * Finds the control instance with the given number-id from the card. | 618 | * Finds the control instance with the given number-id from the card. |
618 | * | 619 | * |
619 | * Returns the pointer of the instance if found, or NULL if not. | ||
620 | * | ||
621 | * The caller must down card->controls_rwsem before calling this function | 620 | * The caller must down card->controls_rwsem before calling this function |
622 | * (if the race condition can happen). | 621 | * (if the race condition can happen). |
622 | * | ||
623 | * Return: The pointer of the instance if found, or %NULL if not. | ||
624 | * | ||
623 | */ | 625 | */ |
624 | struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid) | 626 | struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid) |
625 | { | 627 | { |
@@ -643,10 +645,11 @@ EXPORT_SYMBOL(snd_ctl_find_numid); | |||
643 | * | 645 | * |
644 | * Finds the control instance with the given id from the card. | 646 | * Finds the control instance with the given id from the card. |
645 | * | 647 | * |
646 | * Returns the pointer of the instance if found, or NULL if not. | ||
647 | * | ||
648 | * The caller must down card->controls_rwsem before calling this function | 648 | * The caller must down card->controls_rwsem before calling this function |
649 | * (if the race condition can happen). | 649 | * (if the race condition can happen). |
650 | * | ||
651 | * Return: The pointer of the instance if found, or %NULL if not. | ||
652 | * | ||
650 | */ | 653 | */ |
651 | struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, | 654 | struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, |
652 | struct snd_ctl_elem_id *id) | 655 | struct snd_ctl_elem_id *id) |
@@ -1710,6 +1713,8 @@ EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); | |||
1710 | * Sets all required fields in @info to their appropriate values. | 1713 | * Sets all required fields in @info to their appropriate values. |
1711 | * If the control's accessibility is not the default (readable and writable), | 1714 | * If the control's accessibility is not the default (readable and writable), |
1712 | * the caller has to fill @info->access. | 1715 | * the caller has to fill @info->access. |
1716 | * | ||
1717 | * Return: Zero. | ||
1713 | */ | 1718 | */ |
1714 | int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, | 1719 | int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, |
1715 | unsigned int items, const char *const names[]) | 1720 | unsigned int items, const char *const names[]) |
diff --git a/sound/core/device.c b/sound/core/device.c index f03cb5444a5a..df88defed176 100644 --- a/sound/core/device.c +++ b/sound/core/device.c | |||
@@ -39,7 +39,7 @@ | |||
39 | * The data pointer plays a role as the identifier, too, so the | 39 | * The data pointer plays a role as the identifier, too, so the |
40 | * pointer address must be unique and unchanged. | 40 | * pointer address must be unique and unchanged. |
41 | * | 41 | * |
42 | * Returns zero if successful, or a negative error code on failure. | 42 | * Return: Zero if successful, or a negative error code on failure. |
43 | */ | 43 | */ |
44 | int snd_device_new(struct snd_card *card, snd_device_type_t type, | 44 | int snd_device_new(struct snd_card *card, snd_device_type_t type, |
45 | void *device_data, struct snd_device_ops *ops) | 45 | void *device_data, struct snd_device_ops *ops) |
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(snd_device_new); | |||
73 | * callbacks, dev_disconnect and dev_free, corresponding to the state. | 73 | * callbacks, dev_disconnect and dev_free, corresponding to the state. |
74 | * Then release the device. | 74 | * Then release the device. |
75 | * | 75 | * |
76 | * Returns zero if successful, or a negative error code on failure or if the | 76 | * Return: Zero if successful, or a negative error code on failure or if the |
77 | * device not found. | 77 | * device not found. |
78 | */ | 78 | */ |
79 | int snd_device_free(struct snd_card *card, void *device_data) | 79 | int snd_device_free(struct snd_card *card, void *device_data) |
@@ -116,7 +116,7 @@ EXPORT_SYMBOL(snd_device_free); | |||
116 | * | 116 | * |
117 | * Usually called from snd_card_disconnect(). | 117 | * Usually called from snd_card_disconnect(). |
118 | * | 118 | * |
119 | * Returns zero if successful, or a negative error code on failure or if the | 119 | * Return: Zero if successful, or a negative error code on failure or if the |
120 | * device not found. | 120 | * device not found. |
121 | */ | 121 | */ |
122 | int snd_device_disconnect(struct snd_card *card, void *device_data) | 122 | int snd_device_disconnect(struct snd_card *card, void *device_data) |
@@ -151,7 +151,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data) | |||
151 | * but it can be called later if any new devices are created after | 151 | * but it can be called later if any new devices are created after |
152 | * invocation of snd_card_register(). | 152 | * invocation of snd_card_register(). |
153 | * | 153 | * |
154 | * Returns zero if successful, or a negative error code on failure or if the | 154 | * Return: Zero if successful, or a negative error code on failure or if the |
155 | * device not found. | 155 | * device not found. |
156 | */ | 156 | */ |
157 | int snd_device_register(struct snd_card *card, void *device_data) | 157 | int snd_device_register(struct snd_card *card, void *device_data) |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 3f7f6628cf7b..d105073298cb 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
@@ -356,7 +356,7 @@ static const struct file_operations snd_hwdep_f_ops = | |||
356 | * The callbacks (hwdep->ops) must be set on the returned instance | 356 | * The callbacks (hwdep->ops) must be set on the returned instance |
357 | * after this call manually by the caller. | 357 | * after this call manually by the caller. |
358 | * | 358 | * |
359 | * Returns zero if successful, or a negative error code on failure. | 359 | * Return: Zero if successful, or a negative error code on failure. |
360 | */ | 360 | */ |
361 | int snd_hwdep_new(struct snd_card *card, char *id, int device, | 361 | int snd_hwdep_new(struct snd_card *card, char *id, int device, |
362 | struct snd_hwdep **rhwdep) | 362 | struct snd_hwdep **rhwdep) |
diff --git a/sound/core/info.c b/sound/core/info.c index 3c9bd6b10a96..e79baa11b60e 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -89,7 +89,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer, | |||
89 | char *nbuf; | 89 | char *nbuf; |
90 | 90 | ||
91 | nsize = PAGE_ALIGN(nsize); | 91 | nsize = PAGE_ALIGN(nsize); |
92 | nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL); | 92 | nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL | __GFP_ZERO); |
93 | if (! nbuf) | 93 | if (! nbuf) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
@@ -105,7 +105,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer, | |||
105 | * | 105 | * |
106 | * Outputs the string on the procfs buffer just like printf(). | 106 | * Outputs the string on the procfs buffer just like printf(). |
107 | * | 107 | * |
108 | * Returns the size of output string. | 108 | * Return: The size of output string, or a negative error code. |
109 | */ | 109 | */ |
110 | int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...) | 110 | int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...) |
111 | { | 111 | { |
@@ -344,7 +344,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
344 | goto __nomem; | 344 | goto __nomem; |
345 | data->rbuffer = buffer; | 345 | data->rbuffer = buffer; |
346 | buffer->len = PAGE_SIZE; | 346 | buffer->len = PAGE_SIZE; |
347 | buffer->buffer = kmalloc(buffer->len, GFP_KERNEL); | 347 | buffer->buffer = kzalloc(buffer->len, GFP_KERNEL); |
348 | if (buffer->buffer == NULL) | 348 | if (buffer->buffer == NULL) |
349 | goto __nomem; | 349 | goto __nomem; |
350 | } | 350 | } |
@@ -683,32 +683,27 @@ int snd_info_card_free(struct snd_card *card) | |||
683 | * | 683 | * |
684 | * Reads one line from the buffer and stores the string. | 684 | * Reads one line from the buffer and stores the string. |
685 | * | 685 | * |
686 | * Returns zero if successful, or 1 if error or EOF. | 686 | * Return: Zero if successful, or 1 if error or EOF. |
687 | */ | 687 | */ |
688 | int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) | 688 | int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) |
689 | { | 689 | { |
690 | int c = -1; | 690 | int c = -1; |
691 | 691 | ||
692 | if (snd_BUG_ON(!buffer || !buffer->buffer)) | ||
693 | return 1; | ||
692 | if (len <= 0 || buffer->stop || buffer->error) | 694 | if (len <= 0 || buffer->stop || buffer->error) |
693 | return 1; | 695 | return 1; |
694 | while (--len > 0) { | 696 | while (!buffer->stop) { |
695 | c = buffer->buffer[buffer->curr++]; | 697 | c = buffer->buffer[buffer->curr++]; |
696 | if (c == '\n') { | 698 | if (buffer->curr >= buffer->size) |
697 | if (buffer->curr >= buffer->size) | ||
698 | buffer->stop = 1; | ||
699 | break; | ||
700 | } | ||
701 | *line++ = c; | ||
702 | if (buffer->curr >= buffer->size) { | ||
703 | buffer->stop = 1; | 699 | buffer->stop = 1; |
700 | if (c == '\n') | ||
704 | break; | 701 | break; |
702 | if (len) { | ||
703 | len--; | ||
704 | *line++ = c; | ||
705 | } | 705 | } |
706 | } | 706 | } |
707 | while (c != '\n' && !buffer->stop) { | ||
708 | c = buffer->buffer[buffer->curr++]; | ||
709 | if (buffer->curr >= buffer->size) | ||
710 | buffer->stop = 1; | ||
711 | } | ||
712 | *line = '\0'; | 707 | *line = '\0'; |
713 | return 0; | 708 | return 0; |
714 | } | 709 | } |
@@ -724,7 +719,7 @@ EXPORT_SYMBOL(snd_info_get_line); | |||
724 | * Parses the original string and copy a token to the given | 719 | * Parses the original string and copy a token to the given |
725 | * string buffer. | 720 | * string buffer. |
726 | * | 721 | * |
727 | * Returns the updated pointer of the original string so that | 722 | * Return: The updated pointer of the original string so that |
728 | * it can be used for the next call. | 723 | * it can be used for the next call. |
729 | */ | 724 | */ |
730 | const char *snd_info_get_str(char *dest, const char *src, int len) | 725 | const char *snd_info_get_str(char *dest, const char *src, int len) |
@@ -763,7 +758,7 @@ EXPORT_SYMBOL(snd_info_get_str); | |||
763 | * Usually called from other functions such as | 758 | * Usually called from other functions such as |
764 | * snd_info_create_card_entry(). | 759 | * snd_info_create_card_entry(). |
765 | * | 760 | * |
766 | * Returns the pointer of the new instance, or NULL on failure. | 761 | * Return: The pointer of the new instance, or %NULL on failure. |
767 | */ | 762 | */ |
768 | static struct snd_info_entry *snd_info_create_entry(const char *name) | 763 | static struct snd_info_entry *snd_info_create_entry(const char *name) |
769 | { | 764 | { |
@@ -792,7 +787,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name) | |||
792 | * | 787 | * |
793 | * Creates a new info entry and assigns it to the given module. | 788 | * Creates a new info entry and assigns it to the given module. |
794 | * | 789 | * |
795 | * Returns the pointer of the new instance, or NULL on failure. | 790 | * Return: The pointer of the new instance, or %NULL on failure. |
796 | */ | 791 | */ |
797 | struct snd_info_entry *snd_info_create_module_entry(struct module * module, | 792 | struct snd_info_entry *snd_info_create_module_entry(struct module * module, |
798 | const char *name, | 793 | const char *name, |
@@ -816,7 +811,7 @@ EXPORT_SYMBOL(snd_info_create_module_entry); | |||
816 | * | 811 | * |
817 | * Creates a new info entry and assigns it to the given card. | 812 | * Creates a new info entry and assigns it to the given card. |
818 | * | 813 | * |
819 | * Returns the pointer of the new instance, or NULL on failure. | 814 | * Return: The pointer of the new instance, or %NULL on failure. |
820 | */ | 815 | */ |
821 | struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, | 816 | struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, |
822 | const char *name, | 817 | const char *name, |
@@ -882,7 +877,7 @@ static int snd_info_dev_register_entry(struct snd_device *device) | |||
882 | * For releasing this entry, use snd_device_free() instead of | 877 | * For releasing this entry, use snd_device_free() instead of |
883 | * snd_info_free_entry(). | 878 | * snd_info_free_entry(). |
884 | * | 879 | * |
885 | * Returns zero if successful, or a negative error code on failure. | 880 | * Return: Zero if successful, or a negative error code on failure. |
886 | */ | 881 | */ |
887 | int snd_card_proc_new(struct snd_card *card, const char *name, | 882 | int snd_card_proc_new(struct snd_card *card, const char *name, |
888 | struct snd_info_entry **entryp) | 883 | struct snd_info_entry **entryp) |
@@ -938,7 +933,7 @@ EXPORT_SYMBOL(snd_info_free_entry); | |||
938 | * | 933 | * |
939 | * Registers the proc info entry. | 934 | * Registers the proc info entry. |
940 | * | 935 | * |
941 | * Returns zero if successful, or a negative error code on failure. | 936 | * Return: Zero if successful, or a negative error code on failure. |
942 | */ | 937 | */ |
943 | int snd_info_register(struct snd_info_entry * entry) | 938 | int snd_info_register(struct snd_info_entry * entry) |
944 | { | 939 | { |
diff --git a/sound/core/init.c b/sound/core/init.c index 7b012d15c2cf..6ef06400dfc8 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -144,7 +144,7 @@ static inline int init_info_for_card(struct snd_card *card) | |||
144 | * space for the driver to use freely. The allocated struct is stored | 144 | * space for the driver to use freely. The allocated struct is stored |
145 | * in the given card_ret pointer. | 145 | * in the given card_ret pointer. |
146 | * | 146 | * |
147 | * Returns zero if successful or a negative error code. | 147 | * Return: Zero if successful or a negative error code. |
148 | */ | 148 | */ |
149 | int snd_card_create(int idx, const char *xid, | 149 | int snd_card_create(int idx, const char *xid, |
150 | struct module *module, int extra_size, | 150 | struct module *module, int extra_size, |
@@ -337,7 +337,7 @@ static const struct file_operations snd_shutdown_f_ops = | |||
337 | * | 337 | * |
338 | * Disconnects all APIs from the file-operations (user space). | 338 | * Disconnects all APIs from the file-operations (user space). |
339 | * | 339 | * |
340 | * Returns zero, otherwise a negative error code. | 340 | * Return: Zero, otherwise a negative error code. |
341 | * | 341 | * |
342 | * Note: The current implementation replaces all active file->f_op with special | 342 | * Note: The current implementation replaces all active file->f_op with special |
343 | * dummy file operations (they do nothing except release). | 343 | * dummy file operations (they do nothing except release). |
@@ -415,7 +415,7 @@ EXPORT_SYMBOL(snd_card_disconnect); | |||
415 | * devices automatically. That is, you don't have to release the devices | 415 | * devices automatically. That is, you don't have to release the devices |
416 | * by yourself. | 416 | * by yourself. |
417 | * | 417 | * |
418 | * Returns zero. Frees all associated devices and frees the control | 418 | * Return: Zero. Frees all associated devices and frees the control |
419 | * interface associated to given soundcard. | 419 | * interface associated to given soundcard. |
420 | */ | 420 | */ |
421 | static int snd_card_do_free(struct snd_card *card) | 421 | static int snd_card_do_free(struct snd_card *card) |
@@ -677,7 +677,7 @@ static struct device_attribute card_number_attrs = | |||
677 | * external accesses. Thus, you should call this function at the end | 677 | * external accesses. Thus, you should call this function at the end |
678 | * of the initialization of the card. | 678 | * of the initialization of the card. |
679 | * | 679 | * |
680 | * Returns zero otherwise a negative error code if the registration failed. | 680 | * Return: Zero otherwise a negative error code if the registration failed. |
681 | */ | 681 | */ |
682 | int snd_card_register(struct snd_card *card) | 682 | int snd_card_register(struct snd_card *card) |
683 | { | 683 | { |
@@ -849,7 +849,7 @@ int __exit snd_card_info_done(void) | |||
849 | * This function adds the component id string to the supported list. | 849 | * This function adds the component id string to the supported list. |
850 | * The component can be referred from the alsa-lib. | 850 | * The component can be referred from the alsa-lib. |
851 | * | 851 | * |
852 | * Returns zero otherwise a negative error code. | 852 | * Return: Zero otherwise a negative error code. |
853 | */ | 853 | */ |
854 | 854 | ||
855 | int snd_component_add(struct snd_card *card, const char *component) | 855 | int snd_component_add(struct snd_card *card, const char *component) |
@@ -883,7 +883,7 @@ EXPORT_SYMBOL(snd_component_add); | |||
883 | * This linked-list is used to keep tracking the connection state, | 883 | * This linked-list is used to keep tracking the connection state, |
884 | * and to avoid the release of busy resources by hotplug. | 884 | * and to avoid the release of busy resources by hotplug. |
885 | * | 885 | * |
886 | * Returns zero or a negative error code. | 886 | * Return: zero or a negative error code. |
887 | */ | 887 | */ |
888 | int snd_card_file_add(struct snd_card *card, struct file *file) | 888 | int snd_card_file_add(struct snd_card *card, struct file *file) |
889 | { | 889 | { |
@@ -920,7 +920,7 @@ EXPORT_SYMBOL(snd_card_file_add); | |||
920 | * called beforehand, it processes the pending release of | 920 | * called beforehand, it processes the pending release of |
921 | * resources. | 921 | * resources. |
922 | * | 922 | * |
923 | * Returns zero or a negative error code. | 923 | * Return: Zero or a negative error code. |
924 | */ | 924 | */ |
925 | int snd_card_file_remove(struct snd_card *card, struct file *file) | 925 | int snd_card_file_remove(struct snd_card *card, struct file *file) |
926 | { | 926 | { |
@@ -959,6 +959,8 @@ EXPORT_SYMBOL(snd_card_file_remove); | |||
959 | * | 959 | * |
960 | * Waits until the power-state is changed. | 960 | * Waits until the power-state is changed. |
961 | * | 961 | * |
962 | * Return: Zero if successful, or a negative error code. | ||
963 | * | ||
962 | * Note: the power lock must be active before call. | 964 | * Note: the power lock must be active before call. |
963 | */ | 965 | */ |
964 | int snd_power_wait(struct snd_card *card, unsigned int power_state) | 966 | int snd_power_wait(struct snd_card *card, unsigned int power_state) |
diff --git a/sound/core/isadma.c b/sound/core/isadma.c index c0f1208bb7df..e2b386156a4c 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c | |||
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(snd_dma_disable); | |||
81 | * @dma: the dma number | 81 | * @dma: the dma number |
82 | * @size: the dma transfer size | 82 | * @size: the dma transfer size |
83 | * | 83 | * |
84 | * Returns the current pointer in DMA tranfer buffer in bytes | 84 | * Return: The current pointer in DMA transfer buffer in bytes. |
85 | */ | 85 | */ |
86 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) | 86 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) |
87 | { | 87 | { |
diff --git a/sound/core/jack.c b/sound/core/jack.c index a06b1651fcba..b35fe7345c20 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
@@ -98,8 +98,8 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
98 | * | 98 | * |
99 | * Creates a new jack object. | 99 | * Creates a new jack object. |
100 | * | 100 | * |
101 | * Returns zero if successful, or a negative error code on failure. | 101 | * Return: Zero if successful, or a negative error code on failure. |
102 | * On success jjack will be initialised. | 102 | * On success @jjack will be initialised. |
103 | */ | 103 | */ |
104 | int snd_jack_new(struct snd_card *card, const char *id, int type, | 104 | int snd_jack_new(struct snd_card *card, const char *id, int type, |
105 | struct snd_jack **jjack) | 105 | struct snd_jack **jjack) |
@@ -189,6 +189,8 @@ EXPORT_SYMBOL(snd_jack_set_parent); | |||
189 | * using this abstraction. | 189 | * using this abstraction. |
190 | * | 190 | * |
191 | * This function may only be called prior to registration of the jack. | 191 | * This function may only be called prior to registration of the jack. |
192 | * | ||
193 | * Return: Zero if successful, or a negative error code on failure. | ||
192 | */ | 194 | */ |
193 | int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, | 195 | int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, |
194 | int keytype) | 196 | int keytype) |
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 691569238435..bdf826f4fe0c 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c | |||
@@ -81,7 +81,7 @@ static inline void dec_snd_pages(int order) | |||
81 | * | 81 | * |
82 | * Allocates the physically contiguous pages with the given size. | 82 | * Allocates the physically contiguous pages with the given size. |
83 | * | 83 | * |
84 | * Returns the pointer of the buffer, or NULL if no enoguh memory. | 84 | * Return: The pointer of the buffer, or %NULL if no enough memory. |
85 | */ | 85 | */ |
86 | void *snd_malloc_pages(size_t size, gfp_t gfp_flags) | 86 | void *snd_malloc_pages(size_t size, gfp_t gfp_flags) |
87 | { | 87 | { |
@@ -175,9 +175,9 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, | |||
175 | * | 175 | * |
176 | * Calls the memory-allocator function for the corresponding | 176 | * Calls the memory-allocator function for the corresponding |
177 | * buffer type. | 177 | * buffer type. |
178 | * | 178 | * |
179 | * Returns zero if the buffer with the given size is allocated successfully, | 179 | * Return: Zero if the buffer with the given size is allocated successfully, |
180 | * other a negative value at error. | 180 | * otherwise a negative value on error. |
181 | */ | 181 | */ |
182 | int snd_dma_alloc_pages(int type, struct device *device, size_t size, | 182 | int snd_dma_alloc_pages(int type, struct device *device, size_t size, |
183 | struct snd_dma_buffer *dmab) | 183 | struct snd_dma_buffer *dmab) |
@@ -229,9 +229,9 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, | |||
229 | * buffer type. When no space is left, this function reduces the size and | 229 | * buffer type. When no space is left, this function reduces the size and |
230 | * tries to allocate again. The size actually allocated is stored in | 230 | * tries to allocate again. The size actually allocated is stored in |
231 | * res_size argument. | 231 | * res_size argument. |
232 | * | 232 | * |
233 | * Returns zero if the buffer with the given size is allocated successfully, | 233 | * Return: Zero if the buffer with the given size is allocated successfully, |
234 | * other a negative value at error. | 234 | * otherwise a negative value on error. |
235 | */ | 235 | */ |
236 | int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size, | 236 | int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size, |
237 | struct snd_dma_buffer *dmab) | 237 | struct snd_dma_buffer *dmab) |
@@ -292,7 +292,7 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) | |||
292 | * Looks for the reserved-buffer list and re-uses if the same buffer | 292 | * Looks for the reserved-buffer list and re-uses if the same buffer |
293 | * is found in the list. When the buffer is found, it's removed from the free list. | 293 | * is found in the list. When the buffer is found, it's removed from the free list. |
294 | * | 294 | * |
295 | * Returns the size of buffer if the buffer is found, or zero if not found. | 295 | * Return: The size of buffer if the buffer is found, or zero if not found. |
296 | */ | 296 | */ |
297 | size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) | 297 | size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) |
298 | { | 298 | { |
@@ -326,8 +326,8 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) | |||
326 | * @id: the buffer id | 326 | * @id: the buffer id |
327 | * | 327 | * |
328 | * Reserves the given buffer as a reserved buffer. | 328 | * Reserves the given buffer as a reserved buffer. |
329 | * | 329 | * |
330 | * Returns zero if successful, or a negative code at error. | 330 | * Return: Zero if successful, or a negative code on error. |
331 | */ | 331 | */ |
332 | int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) | 332 | int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) |
333 | { | 333 | { |
diff --git a/sound/core/memory.c b/sound/core/memory.c index 66a278d0b04e..36c0f1a2e189 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * | 33 | * |
34 | * Copies the data from mmio-space to user-space. | 34 | * Copies the data from mmio-space to user-space. |
35 | * | 35 | * |
36 | * Returns zero if successful, or non-zero on failure. | 36 | * Return: Zero if successful, or non-zero on failure. |
37 | */ | 37 | */ |
38 | int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count) | 38 | int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count) |
39 | { | 39 | { |
@@ -66,7 +66,7 @@ EXPORT_SYMBOL(copy_to_user_fromio); | |||
66 | * | 66 | * |
67 | * Copies the data from user-space to mmio-space. | 67 | * Copies the data from user-space to mmio-space. |
68 | * | 68 | * |
69 | * Returns zero if successful, or non-zero on failure. | 69 | * Return: Zero if successful, or non-zero on failure. |
70 | */ | 70 | */ |
71 | int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) | 71 | int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count) |
72 | { | 72 | { |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 61798f85d030..17f45e8aa89c 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -209,6 +209,8 @@ static char *snd_pcm_format_names[] = { | |||
209 | FORMAT(G723_24_1B), | 209 | FORMAT(G723_24_1B), |
210 | FORMAT(G723_40), | 210 | FORMAT(G723_40), |
211 | FORMAT(G723_40_1B), | 211 | FORMAT(G723_40_1B), |
212 | FORMAT(DSD_U8), | ||
213 | FORMAT(DSD_U16_LE), | ||
212 | }; | 214 | }; |
213 | 215 | ||
214 | const char *snd_pcm_format_name(snd_pcm_format_t format) | 216 | const char *snd_pcm_format_name(snd_pcm_format_t format) |
@@ -637,7 +639,7 @@ static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substrea | |||
637 | * calling this, i.e. zero must be given to the argument of | 639 | * calling this, i.e. zero must be given to the argument of |
638 | * snd_pcm_new(). | 640 | * snd_pcm_new(). |
639 | * | 641 | * |
640 | * Returns zero if successful, or a negative error code on failure. | 642 | * Return: Zero if successful, or a negative error code on failure. |
641 | */ | 643 | */ |
642 | int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | 644 | int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) |
643 | { | 645 | { |
@@ -759,7 +761,7 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, | |||
759 | * The pcm operators have to be set afterwards to the new instance | 761 | * The pcm operators have to be set afterwards to the new instance |
760 | * via snd_pcm_set_ops(). | 762 | * via snd_pcm_set_ops(). |
761 | * | 763 | * |
762 | * Returns zero if successful, or a negative error code on failure. | 764 | * Return: Zero if successful, or a negative error code on failure. |
763 | */ | 765 | */ |
764 | int snd_pcm_new(struct snd_card *card, const char *id, int device, | 766 | int snd_pcm_new(struct snd_card *card, const char *id, int device, |
765 | int playback_count, int capture_count, struct snd_pcm **rpcm) | 767 | int playback_count, int capture_count, struct snd_pcm **rpcm) |
@@ -787,7 +789,7 @@ EXPORT_SYMBOL(snd_pcm_new); | |||
787 | * The pcm operators have to be set afterwards to the new instance | 789 | * The pcm operators have to be set afterwards to the new instance |
788 | * via snd_pcm_set_ops(). | 790 | * via snd_pcm_set_ops(). |
789 | * | 791 | * |
790 | * Returns zero if successful, or a negative error code on failure. | 792 | * Return: Zero if successful, or a negative error code on failure. |
791 | */ | 793 | */ |
792 | int snd_pcm_new_internal(struct snd_card *card, const char *id, int device, | 794 | int snd_pcm_new_internal(struct snd_card *card, const char *id, int device, |
793 | int playback_count, int capture_count, | 795 | int playback_count, int capture_count, |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index c4840ff75d00..41b3dfe68698 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -666,7 +666,8 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, | |||
666 | * The interval is changed to the range satisfying both intervals. | 666 | * The interval is changed to the range satisfying both intervals. |
667 | * The interval status (min, max, integer, etc.) are evaluated. | 667 | * The interval status (min, max, integer, etc.) are evaluated. |
668 | * | 668 | * |
669 | * Returns non-zero if the value is changed, zero if not changed. | 669 | * Return: Positive if the value is changed, zero if it's not changed, or a |
670 | * negative error code. | ||
670 | */ | 671 | */ |
671 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) | 672 | int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) |
672 | { | 673 | { |
@@ -865,7 +866,8 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, | |||
865 | * @nump: pointer to store the resultant numerator | 866 | * @nump: pointer to store the resultant numerator |
866 | * @denp: pointer to store the resultant denominator | 867 | * @denp: pointer to store the resultant denominator |
867 | * | 868 | * |
868 | * Returns non-zero if the value is changed, zero if not changed. | 869 | * Return: Positive if the value is changed, zero if it's not changed, or a |
870 | * negative error code. | ||
869 | */ | 871 | */ |
870 | int snd_interval_ratnum(struct snd_interval *i, | 872 | int snd_interval_ratnum(struct snd_interval *i, |
871 | unsigned int rats_count, struct snd_ratnum *rats, | 873 | unsigned int rats_count, struct snd_ratnum *rats, |
@@ -983,7 +985,8 @@ EXPORT_SYMBOL(snd_interval_ratnum); | |||
983 | * @nump: pointer to store the resultant numerator | 985 | * @nump: pointer to store the resultant numerator |
984 | * @denp: pointer to store the resultant denominator | 986 | * @denp: pointer to store the resultant denominator |
985 | * | 987 | * |
986 | * Returns non-zero if the value is changed, zero if not changed. | 988 | * Return: Positive if the value is changed, zero if it's not changed, or a |
989 | * negative error code. | ||
987 | */ | 990 | */ |
988 | static int snd_interval_ratden(struct snd_interval *i, | 991 | static int snd_interval_ratden(struct snd_interval *i, |
989 | unsigned int rats_count, struct snd_ratden *rats, | 992 | unsigned int rats_count, struct snd_ratden *rats, |
@@ -1082,7 +1085,8 @@ static int snd_interval_ratden(struct snd_interval *i, | |||
1082 | * When mask is non-zero, only the elements corresponding to bit 1 are | 1085 | * When mask is non-zero, only the elements corresponding to bit 1 are |
1083 | * evaluated. | 1086 | * evaluated. |
1084 | * | 1087 | * |
1085 | * Returns non-zero if the value is changed, zero if not changed. | 1088 | * Return: Positive if the value is changed, zero if it's not changed, or a |
1089 | * negative error code. | ||
1086 | */ | 1090 | */ |
1087 | int snd_interval_list(struct snd_interval *i, unsigned int count, | 1091 | int snd_interval_list(struct snd_interval *i, unsigned int count, |
1088 | const unsigned int *list, unsigned int mask) | 1092 | const unsigned int *list, unsigned int mask) |
@@ -1142,7 +1146,7 @@ static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned | |||
1142 | * @private: the private data pointer passed to function | 1146 | * @private: the private data pointer passed to function |
1143 | * @dep: the dependent variables | 1147 | * @dep: the dependent variables |
1144 | * | 1148 | * |
1145 | * Returns zero if successful, or a negative error code on failure. | 1149 | * Return: Zero if successful, or a negative error code on failure. |
1146 | */ | 1150 | */ |
1147 | int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | 1151 | int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, |
1148 | int var, | 1152 | int var, |
@@ -1200,6 +1204,8 @@ EXPORT_SYMBOL(snd_pcm_hw_rule_add); | |||
1200 | * @mask: the bitmap mask | 1204 | * @mask: the bitmap mask |
1201 | * | 1205 | * |
1202 | * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. | 1206 | * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. |
1207 | * | ||
1208 | * Return: Zero if successful, or a negative error code on failure. | ||
1203 | */ | 1209 | */ |
1204 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 1210 | int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
1205 | u_int32_t mask) | 1211 | u_int32_t mask) |
@@ -1220,6 +1226,8 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param | |||
1220 | * @mask: the 64bit bitmap mask | 1226 | * @mask: the 64bit bitmap mask |
1221 | * | 1227 | * |
1222 | * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. | 1228 | * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. |
1229 | * | ||
1230 | * Return: Zero if successful, or a negative error code on failure. | ||
1223 | */ | 1231 | */ |
1224 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 1232 | int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
1225 | u_int64_t mask) | 1233 | u_int64_t mask) |
@@ -1240,6 +1248,9 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par | |||
1240 | * @var: hw_params variable to apply the integer constraint | 1248 | * @var: hw_params variable to apply the integer constraint |
1241 | * | 1249 | * |
1242 | * Apply the constraint of integer to an interval parameter. | 1250 | * Apply the constraint of integer to an interval parameter. |
1251 | * | ||
1252 | * Return: Positive if the value is changed, zero if it's not changed, or a | ||
1253 | * negative error code. | ||
1243 | */ | 1254 | */ |
1244 | int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var) | 1255 | int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var) |
1245 | { | 1256 | { |
@@ -1257,6 +1268,9 @@ EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); | |||
1257 | * @max: the maximal value | 1268 | * @max: the maximal value |
1258 | * | 1269 | * |
1259 | * Apply the min/max range constraint to an interval parameter. | 1270 | * Apply the min/max range constraint to an interval parameter. |
1271 | * | ||
1272 | * Return: Positive if the value is changed, zero if it's not changed, or a | ||
1273 | * negative error code. | ||
1260 | */ | 1274 | */ |
1261 | int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, | 1275 | int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, |
1262 | unsigned int min, unsigned int max) | 1276 | unsigned int min, unsigned int max) |
@@ -1288,6 +1302,8 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, | |||
1288 | * @l: list | 1302 | * @l: list |
1289 | * | 1303 | * |
1290 | * Apply the list of constraints to an interval parameter. | 1304 | * Apply the list of constraints to an interval parameter. |
1305 | * | ||
1306 | * Return: Zero if successful, or a negative error code on failure. | ||
1291 | */ | 1307 | */ |
1292 | int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, | 1308 | int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, |
1293 | unsigned int cond, | 1309 | unsigned int cond, |
@@ -1322,6 +1338,8 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, | |||
1322 | * @cond: condition bits | 1338 | * @cond: condition bits |
1323 | * @var: hw_params variable to apply the ratnums constraint | 1339 | * @var: hw_params variable to apply the ratnums constraint |
1324 | * @r: struct snd_ratnums constriants | 1340 | * @r: struct snd_ratnums constriants |
1341 | * | ||
1342 | * Return: Zero if successful, or a negative error code on failure. | ||
1325 | */ | 1343 | */ |
1326 | int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, | 1344 | int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, |
1327 | unsigned int cond, | 1345 | unsigned int cond, |
@@ -1355,6 +1373,8 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, | |||
1355 | * @cond: condition bits | 1373 | * @cond: condition bits |
1356 | * @var: hw_params variable to apply the ratdens constraint | 1374 | * @var: hw_params variable to apply the ratdens constraint |
1357 | * @r: struct snd_ratdens constriants | 1375 | * @r: struct snd_ratdens constriants |
1376 | * | ||
1377 | * Return: Zero if successful, or a negative error code on failure. | ||
1358 | */ | 1378 | */ |
1359 | int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, | 1379 | int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, |
1360 | unsigned int cond, | 1380 | unsigned int cond, |
@@ -1386,6 +1406,8 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, | |||
1386 | * @cond: condition bits | 1406 | * @cond: condition bits |
1387 | * @width: sample bits width | 1407 | * @width: sample bits width |
1388 | * @msbits: msbits width | 1408 | * @msbits: msbits width |
1409 | * | ||
1410 | * Return: Zero if successful, or a negative error code on failure. | ||
1389 | */ | 1411 | */ |
1390 | int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, | 1412 | int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, |
1391 | unsigned int cond, | 1413 | unsigned int cond, |
@@ -1414,6 +1436,8 @@ static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, | |||
1414 | * @cond: condition bits | 1436 | * @cond: condition bits |
1415 | * @var: hw_params variable to apply the step constraint | 1437 | * @var: hw_params variable to apply the step constraint |
1416 | * @step: step size | 1438 | * @step: step size |
1439 | * | ||
1440 | * Return: Zero if successful, or a negative error code on failure. | ||
1417 | */ | 1441 | */ |
1418 | int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, | 1442 | int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, |
1419 | unsigned int cond, | 1443 | unsigned int cond, |
@@ -1444,6 +1468,8 @@ static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm | |||
1444 | * @runtime: PCM runtime instance | 1468 | * @runtime: PCM runtime instance |
1445 | * @cond: condition bits | 1469 | * @cond: condition bits |
1446 | * @var: hw_params variable to apply the power-of-2 constraint | 1470 | * @var: hw_params variable to apply the power-of-2 constraint |
1471 | * | ||
1472 | * Return: Zero if successful, or a negative error code on failure. | ||
1447 | */ | 1473 | */ |
1448 | int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, | 1474 | int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, |
1449 | unsigned int cond, | 1475 | unsigned int cond, |
@@ -1470,6 +1496,8 @@ static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params, | |||
1470 | * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling | 1496 | * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling |
1471 | * @runtime: PCM runtime instance | 1497 | * @runtime: PCM runtime instance |
1472 | * @base_rate: the rate at which the hardware does not resample | 1498 | * @base_rate: the rate at which the hardware does not resample |
1499 | * | ||
1500 | * Return: Zero if successful, or a negative error code on failure. | ||
1473 | */ | 1501 | */ |
1474 | int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime, | 1502 | int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime, |
1475 | unsigned int base_rate) | 1503 | unsigned int base_rate) |
@@ -1519,8 +1547,8 @@ EXPORT_SYMBOL(_snd_pcm_hw_params_any); | |||
1519 | * @var: parameter to retrieve | 1547 | * @var: parameter to retrieve |
1520 | * @dir: pointer to the direction (-1,0,1) or %NULL | 1548 | * @dir: pointer to the direction (-1,0,1) or %NULL |
1521 | * | 1549 | * |
1522 | * Return the value for field @var if it's fixed in configuration space | 1550 | * Return: The value for field @var if it's fixed in configuration space |
1523 | * defined by @params. Return -%EINVAL otherwise. | 1551 | * defined by @params. -%EINVAL otherwise. |
1524 | */ | 1552 | */ |
1525 | int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, | 1553 | int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, |
1526 | snd_pcm_hw_param_t var, int *dir) | 1554 | snd_pcm_hw_param_t var, int *dir) |
@@ -1591,7 +1619,8 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1591 | * | 1619 | * |
1592 | * Inside configuration space defined by @params remove from @var all | 1620 | * Inside configuration space defined by @params remove from @var all |
1593 | * values > minimum. Reduce configuration space accordingly. | 1621 | * values > minimum. Reduce configuration space accordingly. |
1594 | * Return the minimum. | 1622 | * |
1623 | * Return: The minimum, or a negative error code on failure. | ||
1595 | */ | 1624 | */ |
1596 | int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, | 1625 | int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, |
1597 | struct snd_pcm_hw_params *params, | 1626 | struct snd_pcm_hw_params *params, |
@@ -1637,7 +1666,8 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1637 | * | 1666 | * |
1638 | * Inside configuration space defined by @params remove from @var all | 1667 | * Inside configuration space defined by @params remove from @var all |
1639 | * values < maximum. Reduce configuration space accordingly. | 1668 | * values < maximum. Reduce configuration space accordingly. |
1640 | * Return the maximum. | 1669 | * |
1670 | * Return: The maximum, or a negative error code on failure. | ||
1641 | */ | 1671 | */ |
1642 | int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, | 1672 | int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, |
1643 | struct snd_pcm_hw_params *params, | 1673 | struct snd_pcm_hw_params *params, |
@@ -1665,6 +1695,8 @@ EXPORT_SYMBOL(snd_pcm_hw_param_last); | |||
1665 | * The configuration chosen is that obtained fixing in this order: | 1695 | * The configuration chosen is that obtained fixing in this order: |
1666 | * first access, first format, first subformat, min channels, | 1696 | * first access, first format, first subformat, min channels, |
1667 | * min rate, min period time, max buffer size, min tick time | 1697 | * min rate, min period time, max buffer size, min tick time |
1698 | * | ||
1699 | * Return: Zero if successful, or a negative error code on failure. | ||
1668 | */ | 1700 | */ |
1669 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, | 1701 | int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, |
1670 | struct snd_pcm_hw_params *params) | 1702 | struct snd_pcm_hw_params *params) |
@@ -1771,7 +1803,7 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, | |||
1771 | * Processes the generic ioctl commands for PCM. | 1803 | * Processes the generic ioctl commands for PCM. |
1772 | * Can be passed as the ioctl callback for PCM ops. | 1804 | * Can be passed as the ioctl callback for PCM ops. |
1773 | * | 1805 | * |
1774 | * Returns zero if successful, or a negative error code on failure. | 1806 | * Return: Zero if successful, or a negative error code on failure. |
1775 | */ | 1807 | */ |
1776 | int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, | 1808 | int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, |
1777 | unsigned int cmd, void *arg) | 1809 | unsigned int cmd, void *arg) |
@@ -2510,7 +2542,7 @@ static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol) | |||
2510 | * @info_ret: store struct snd_pcm_chmap instance if non-NULL | 2542 | * @info_ret: store struct snd_pcm_chmap instance if non-NULL |
2511 | * | 2543 | * |
2512 | * Create channel-mapping control elements assigned to the given PCM stream(s). | 2544 | * Create channel-mapping control elements assigned to the given PCM stream(s). |
2513 | * Returns zero if succeed, or a negative error value. | 2545 | * Return: Zero if successful, or a negative error value. |
2514 | */ | 2546 | */ |
2515 | int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, | 2547 | int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, |
2516 | const struct snd_pcm_chmap_elem *chmap, | 2548 | const struct snd_pcm_chmap_elem *chmap, |
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 69e01c4fc32d..0af622c34e19 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c | |||
@@ -95,7 +95,7 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream | |||
95 | * | 95 | * |
96 | * Releases the pre-allocated buffer of the given substream. | 96 | * Releases the pre-allocated buffer of the given substream. |
97 | * | 97 | * |
98 | * Returns zero if successful, or a negative error code on failure. | 98 | * Return: Zero if successful, or a negative error code on failure. |
99 | */ | 99 | */ |
100 | int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) | 100 | int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) |
101 | { | 101 | { |
@@ -115,7 +115,7 @@ int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream) | |||
115 | * | 115 | * |
116 | * Releases all the pre-allocated buffers on the given pcm. | 116 | * Releases all the pre-allocated buffers on the given pcm. |
117 | * | 117 | * |
118 | * Returns zero if successful, or a negative error code on failure. | 118 | * Return: Zero if successful, or a negative error code on failure. |
119 | */ | 119 | */ |
120 | int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) | 120 | int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm) |
121 | { | 121 | { |
@@ -265,7 +265,7 @@ static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream, | |||
265 | * destruction time. The dma_buf_id must be unique for all systems | 265 | * destruction time. The dma_buf_id must be unique for all systems |
266 | * (in the same DMA buffer type) e.g. using snd_dma_pci_buf_id(). | 266 | * (in the same DMA buffer type) e.g. using snd_dma_pci_buf_id(). |
267 | * | 267 | * |
268 | * Returns zero if successful, or a negative error code on failure. | 268 | * Return: Zero if successful, or a negative error code on failure. |
269 | */ | 269 | */ |
270 | int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, | 270 | int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, |
271 | int type, struct device *data, | 271 | int type, struct device *data, |
@@ -289,7 +289,7 @@ EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); | |||
289 | * Do pre-allocation to all substreams of the given pcm for the | 289 | * Do pre-allocation to all substreams of the given pcm for the |
290 | * specified DMA type. | 290 | * specified DMA type. |
291 | * | 291 | * |
292 | * Returns zero if successful, or a negative error code on failure. | 292 | * Return: Zero if successful, or a negative error code on failure. |
293 | */ | 293 | */ |
294 | int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, | 294 | int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, |
295 | int type, void *data, | 295 | int type, void *data, |
@@ -313,8 +313,9 @@ EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); | |||
313 | * @substream: the pcm substream instance | 313 | * @substream: the pcm substream instance |
314 | * @offset: the buffer offset | 314 | * @offset: the buffer offset |
315 | * | 315 | * |
316 | * Returns the page struct at the given buffer offset. | ||
317 | * Used as the page callback of PCM ops. | 316 | * Used as the page callback of PCM ops. |
317 | * | ||
318 | * Return: The page struct at the given buffer offset. %NULL on failure. | ||
318 | */ | 319 | */ |
319 | struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) | 320 | struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) |
320 | { | 321 | { |
@@ -337,7 +338,7 @@ EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); | |||
337 | * Allocates the DMA buffer on the BUS type given earlier to | 338 | * Allocates the DMA buffer on the BUS type given earlier to |
338 | * snd_pcm_lib_preallocate_xxx_pages(). | 339 | * snd_pcm_lib_preallocate_xxx_pages(). |
339 | * | 340 | * |
340 | * Returns 1 if the buffer is changed, 0 if not changed, or a negative | 341 | * Return: 1 if the buffer is changed, 0 if not changed, or a negative |
341 | * code on failure. | 342 | * code on failure. |
342 | */ | 343 | */ |
343 | int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) | 344 | int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) |
@@ -390,7 +391,7 @@ EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); | |||
390 | * | 391 | * |
391 | * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). | 392 | * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). |
392 | * | 393 | * |
393 | * Returns zero if successful, or a negative error code on failure. | 394 | * Return: Zero if successful, or a negative error code on failure. |
394 | */ | 395 | */ |
395 | int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) | 396 | int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) |
396 | { | 397 | { |
@@ -437,6 +438,8 @@ EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer); | |||
437 | * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer | 438 | * snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer |
438 | * @substream: the substream with a buffer allocated by | 439 | * @substream: the substream with a buffer allocated by |
439 | * snd_pcm_lib_alloc_vmalloc_buffer() | 440 | * snd_pcm_lib_alloc_vmalloc_buffer() |
441 | * | ||
442 | * Return: Zero if successful, or a negative error code on failure. | ||
440 | */ | 443 | */ |
441 | int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) | 444 | int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream) |
442 | { | 445 | { |
@@ -458,6 +461,8 @@ EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer); | |||
458 | * @offset: offset in the buffer | 461 | * @offset: offset in the buffer |
459 | * | 462 | * |
460 | * This function is to be used as the page callback in the PCM ops. | 463 | * This function is to be used as the page callback in the PCM ops. |
464 | * | ||
465 | * Return: The page struct, or %NULL on failure. | ||
461 | */ | 466 | */ |
462 | struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, | 467 | struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, |
463 | unsigned long offset) | 468 | unsigned long offset) |
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index d4fc1bfbe457..43f24cce3dec 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -140,6 +140,14 @@ static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { | |||
140 | .width = 5, .phys = 5, .le = -1, .signd = -1, | 140 | .width = 5, .phys = 5, .le = -1, .signd = -1, |
141 | .silence = {}, | 141 | .silence = {}, |
142 | }, | 142 | }, |
143 | [SNDRV_PCM_FORMAT_DSD_U8] = { | ||
144 | .width = 8, .phys = 8, .le = 1, .signd = 0, | ||
145 | .silence = {}, | ||
146 | }, | ||
147 | [SNDRV_PCM_FORMAT_DSD_U16_LE] = { | ||
148 | .width = 16, .phys = 16, .le = 1, .signd = 0, | ||
149 | .silence = {}, | ||
150 | }, | ||
143 | /* FIXME: the following three formats are not defined properly yet */ | 151 | /* FIXME: the following three formats are not defined properly yet */ |
144 | [SNDRV_PCM_FORMAT_MPEG] = { | 152 | [SNDRV_PCM_FORMAT_MPEG] = { |
145 | .le = -1, .signd = -1, | 153 | .le = -1, .signd = -1, |
@@ -213,7 +221,7 @@ static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { | |||
213 | * snd_pcm_format_signed - Check the PCM format is signed linear | 221 | * snd_pcm_format_signed - Check the PCM format is signed linear |
214 | * @format: the format to check | 222 | * @format: the format to check |
215 | * | 223 | * |
216 | * Returns 1 if the given PCM format is signed linear, 0 if unsigned | 224 | * Return: 1 if the given PCM format is signed linear, 0 if unsigned |
217 | * linear, and a negative error code for non-linear formats. | 225 | * linear, and a negative error code for non-linear formats. |
218 | */ | 226 | */ |
219 | int snd_pcm_format_signed(snd_pcm_format_t format) | 227 | int snd_pcm_format_signed(snd_pcm_format_t format) |
@@ -232,7 +240,7 @@ EXPORT_SYMBOL(snd_pcm_format_signed); | |||
232 | * snd_pcm_format_unsigned - Check the PCM format is unsigned linear | 240 | * snd_pcm_format_unsigned - Check the PCM format is unsigned linear |
233 | * @format: the format to check | 241 | * @format: the format to check |
234 | * | 242 | * |
235 | * Returns 1 if the given PCM format is unsigned linear, 0 if signed | 243 | * Return: 1 if the given PCM format is unsigned linear, 0 if signed |
236 | * linear, and a negative error code for non-linear formats. | 244 | * linear, and a negative error code for non-linear formats. |
237 | */ | 245 | */ |
238 | int snd_pcm_format_unsigned(snd_pcm_format_t format) | 246 | int snd_pcm_format_unsigned(snd_pcm_format_t format) |
@@ -251,7 +259,7 @@ EXPORT_SYMBOL(snd_pcm_format_unsigned); | |||
251 | * snd_pcm_format_linear - Check the PCM format is linear | 259 | * snd_pcm_format_linear - Check the PCM format is linear |
252 | * @format: the format to check | 260 | * @format: the format to check |
253 | * | 261 | * |
254 | * Returns 1 if the given PCM format is linear, 0 if not. | 262 | * Return: 1 if the given PCM format is linear, 0 if not. |
255 | */ | 263 | */ |
256 | int snd_pcm_format_linear(snd_pcm_format_t format) | 264 | int snd_pcm_format_linear(snd_pcm_format_t format) |
257 | { | 265 | { |
@@ -264,7 +272,7 @@ EXPORT_SYMBOL(snd_pcm_format_linear); | |||
264 | * snd_pcm_format_little_endian - Check the PCM format is little-endian | 272 | * snd_pcm_format_little_endian - Check the PCM format is little-endian |
265 | * @format: the format to check | 273 | * @format: the format to check |
266 | * | 274 | * |
267 | * Returns 1 if the given PCM format is little-endian, 0 if | 275 | * Return: 1 if the given PCM format is little-endian, 0 if |
268 | * big-endian, or a negative error code if endian not specified. | 276 | * big-endian, or a negative error code if endian not specified. |
269 | */ | 277 | */ |
270 | int snd_pcm_format_little_endian(snd_pcm_format_t format) | 278 | int snd_pcm_format_little_endian(snd_pcm_format_t format) |
@@ -283,7 +291,7 @@ EXPORT_SYMBOL(snd_pcm_format_little_endian); | |||
283 | * snd_pcm_format_big_endian - Check the PCM format is big-endian | 291 | * snd_pcm_format_big_endian - Check the PCM format is big-endian |
284 | * @format: the format to check | 292 | * @format: the format to check |
285 | * | 293 | * |
286 | * Returns 1 if the given PCM format is big-endian, 0 if | 294 | * Return: 1 if the given PCM format is big-endian, 0 if |
287 | * little-endian, or a negative error code if endian not specified. | 295 | * little-endian, or a negative error code if endian not specified. |
288 | */ | 296 | */ |
289 | int snd_pcm_format_big_endian(snd_pcm_format_t format) | 297 | int snd_pcm_format_big_endian(snd_pcm_format_t format) |
@@ -302,7 +310,7 @@ EXPORT_SYMBOL(snd_pcm_format_big_endian); | |||
302 | * snd_pcm_format_width - return the bit-width of the format | 310 | * snd_pcm_format_width - return the bit-width of the format |
303 | * @format: the format to check | 311 | * @format: the format to check |
304 | * | 312 | * |
305 | * Returns the bit-width of the format, or a negative error code | 313 | * Return: The bit-width of the format, or a negative error code |
306 | * if unknown format. | 314 | * if unknown format. |
307 | */ | 315 | */ |
308 | int snd_pcm_format_width(snd_pcm_format_t format) | 316 | int snd_pcm_format_width(snd_pcm_format_t format) |
@@ -321,7 +329,7 @@ EXPORT_SYMBOL(snd_pcm_format_width); | |||
321 | * snd_pcm_format_physical_width - return the physical bit-width of the format | 329 | * snd_pcm_format_physical_width - return the physical bit-width of the format |
322 | * @format: the format to check | 330 | * @format: the format to check |
323 | * | 331 | * |
324 | * Returns the physical bit-width of the format, or a negative error code | 332 | * Return: The physical bit-width of the format, or a negative error code |
325 | * if unknown format. | 333 | * if unknown format. |
326 | */ | 334 | */ |
327 | int snd_pcm_format_physical_width(snd_pcm_format_t format) | 335 | int snd_pcm_format_physical_width(snd_pcm_format_t format) |
@@ -341,7 +349,7 @@ EXPORT_SYMBOL(snd_pcm_format_physical_width); | |||
341 | * @format: the format to check | 349 | * @format: the format to check |
342 | * @samples: sampling rate | 350 | * @samples: sampling rate |
343 | * | 351 | * |
344 | * Returns the byte size of the given samples for the format, or a | 352 | * Return: The byte size of the given samples for the format, or a |
345 | * negative error code if unknown format. | 353 | * negative error code if unknown format. |
346 | */ | 354 | */ |
347 | ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) | 355 | ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) |
@@ -358,7 +366,7 @@ EXPORT_SYMBOL(snd_pcm_format_size); | |||
358 | * snd_pcm_format_silence_64 - return the silent data in 8 bytes array | 366 | * snd_pcm_format_silence_64 - return the silent data in 8 bytes array |
359 | * @format: the format to check | 367 | * @format: the format to check |
360 | * | 368 | * |
361 | * Returns the format pattern to fill or NULL if error. | 369 | * Return: The format pattern to fill or %NULL if error. |
362 | */ | 370 | */ |
363 | const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) | 371 | const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) |
364 | { | 372 | { |
@@ -379,7 +387,7 @@ EXPORT_SYMBOL(snd_pcm_format_silence_64); | |||
379 | * | 387 | * |
380 | * Sets the silence data on the buffer for the given samples. | 388 | * Sets the silence data on the buffer for the given samples. |
381 | * | 389 | * |
382 | * Returns zero if successful, or a negative error code on failure. | 390 | * Return: Zero if successful, or a negative error code on failure. |
383 | */ | 391 | */ |
384 | int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) | 392 | int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) |
385 | { | 393 | { |
@@ -449,7 +457,7 @@ EXPORT_SYMBOL(snd_pcm_format_set_silence); | |||
449 | * Determines the rate_min and rate_max fields from the rates bits of | 457 | * Determines the rate_min and rate_max fields from the rates bits of |
450 | * the given runtime->hw. | 458 | * the given runtime->hw. |
451 | * | 459 | * |
452 | * Returns zero if successful. | 460 | * Return: Zero if successful. |
453 | */ | 461 | */ |
454 | int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) | 462 | int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) |
455 | { | 463 | { |
@@ -475,7 +483,7 @@ EXPORT_SYMBOL(snd_pcm_limit_hw_rates); | |||
475 | * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit | 483 | * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit |
476 | * @rate: the sample rate to convert | 484 | * @rate: the sample rate to convert |
477 | * | 485 | * |
478 | * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or | 486 | * Return: The SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or |
479 | * SNDRV_PCM_RATE_KNOT for an unknown rate. | 487 | * SNDRV_PCM_RATE_KNOT for an unknown rate. |
480 | */ | 488 | */ |
481 | unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) | 489 | unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) |
@@ -493,8 +501,8 @@ EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); | |||
493 | * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate | 501 | * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate |
494 | * @rate_bit: the rate bit to convert | 502 | * @rate_bit: the rate bit to convert |
495 | * | 503 | * |
496 | * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag | 504 | * Return: The sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag |
497 | * or 0 for an unknown rate bit | 505 | * or 0 for an unknown rate bit. |
498 | */ | 506 | */ |
499 | unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) | 507 | unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) |
500 | { | 508 | { |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index eb560fa32321..23e3c46cd0a4 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -898,6 +898,8 @@ static struct action_ops snd_pcm_action_start = { | |||
898 | /** | 898 | /** |
899 | * snd_pcm_start - start all linked streams | 899 | * snd_pcm_start - start all linked streams |
900 | * @substream: the PCM substream instance | 900 | * @substream: the PCM substream instance |
901 | * | ||
902 | * Return: Zero if successful, or a negative error code. | ||
901 | */ | 903 | */ |
902 | int snd_pcm_start(struct snd_pcm_substream *substream) | 904 | int snd_pcm_start(struct snd_pcm_substream *substream) |
903 | { | 905 | { |
@@ -951,6 +953,8 @@ static struct action_ops snd_pcm_action_stop = { | |||
951 | * @state: PCM state after stopping the stream | 953 | * @state: PCM state after stopping the stream |
952 | * | 954 | * |
953 | * The state of each stream is then changed to the given state unconditionally. | 955 | * The state of each stream is then changed to the given state unconditionally. |
956 | * | ||
957 | * Return: Zero if succesful, or a negative error code. | ||
954 | */ | 958 | */ |
955 | int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state) | 959 | int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state) |
956 | { | 960 | { |
@@ -965,6 +969,8 @@ EXPORT_SYMBOL(snd_pcm_stop); | |||
965 | * | 969 | * |
966 | * After stopping, the state is changed to SETUP. | 970 | * After stopping, the state is changed to SETUP. |
967 | * Unlike snd_pcm_stop(), this affects only the given stream. | 971 | * Unlike snd_pcm_stop(), this affects only the given stream. |
972 | * | ||
973 | * Return: Zero if succesful, or a negative error code. | ||
968 | */ | 974 | */ |
969 | int snd_pcm_drain_done(struct snd_pcm_substream *substream) | 975 | int snd_pcm_drain_done(struct snd_pcm_substream *substream) |
970 | { | 976 | { |
@@ -1098,6 +1104,9 @@ static struct action_ops snd_pcm_action_suspend = { | |||
1098 | * @substream: the PCM substream | 1104 | * @substream: the PCM substream |
1099 | * | 1105 | * |
1100 | * After this call, all streams are changed to SUSPENDED state. | 1106 | * After this call, all streams are changed to SUSPENDED state. |
1107 | * | ||
1108 | * Return: Zero if successful (or @substream is %NULL), or a negative error | ||
1109 | * code. | ||
1101 | */ | 1110 | */ |
1102 | int snd_pcm_suspend(struct snd_pcm_substream *substream) | 1111 | int snd_pcm_suspend(struct snd_pcm_substream *substream) |
1103 | { | 1112 | { |
@@ -1120,6 +1129,8 @@ EXPORT_SYMBOL(snd_pcm_suspend); | |||
1120 | * @pcm: the PCM instance | 1129 | * @pcm: the PCM instance |
1121 | * | 1130 | * |
1122 | * After this call, all streams are changed to SUSPENDED state. | 1131 | * After this call, all streams are changed to SUSPENDED state. |
1132 | * | ||
1133 | * Return: Zero if successful (or @pcm is %NULL), or a negative error code. | ||
1123 | */ | 1134 | */ |
1124 | int snd_pcm_suspend_all(struct snd_pcm *pcm) | 1135 | int snd_pcm_suspend_all(struct snd_pcm *pcm) |
1125 | { | 1136 | { |
@@ -1343,6 +1354,8 @@ static struct action_ops snd_pcm_action_prepare = { | |||
1343 | * snd_pcm_prepare - prepare the PCM substream to be triggerable | 1354 | * snd_pcm_prepare - prepare the PCM substream to be triggerable |
1344 | * @substream: the PCM substream instance | 1355 | * @substream: the PCM substream instance |
1345 | * @file: file to refer f_flags | 1356 | * @file: file to refer f_flags |
1357 | * | ||
1358 | * Return: Zero if successful, or a negative error code. | ||
1346 | */ | 1359 | */ |
1347 | static int snd_pcm_prepare(struct snd_pcm_substream *substream, | 1360 | static int snd_pcm_prepare(struct snd_pcm_substream *substream, |
1348 | struct file *file) | 1361 | struct file *file) |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 1bb95aeea084..7b596b5751db 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -863,7 +863,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
863 | * | 863 | * |
864 | * Reads the data from the internal buffer. | 864 | * Reads the data from the internal buffer. |
865 | * | 865 | * |
866 | * Returns the size of read data, or a negative error code on failure. | 866 | * Return: The size of read data, or a negative error code on failure. |
867 | */ | 867 | */ |
868 | int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, | 868 | int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, |
869 | const unsigned char *buffer, int count) | 869 | const unsigned char *buffer, int count) |
@@ -1024,8 +1024,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun | |||
1024 | /** | 1024 | /** |
1025 | * snd_rawmidi_transmit_empty - check whether the output buffer is empty | 1025 | * snd_rawmidi_transmit_empty - check whether the output buffer is empty |
1026 | * @substream: the rawmidi substream | 1026 | * @substream: the rawmidi substream |
1027 | * | 1027 | * |
1028 | * Returns 1 if the internal output buffer is empty, 0 if not. | 1028 | * Return: 1 if the internal output buffer is empty, 0 if not. |
1029 | */ | 1029 | */ |
1030 | int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) | 1030 | int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) |
1031 | { | 1031 | { |
@@ -1055,7 +1055,7 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) | |||
1055 | * and call snd_rawmidi_transmit_ack() after the transmission is | 1055 | * and call snd_rawmidi_transmit_ack() after the transmission is |
1056 | * finished. | 1056 | * finished. |
1057 | * | 1057 | * |
1058 | * Returns the size of copied data, or a negative error code on failure. | 1058 | * Return: The size of copied data, or a negative error code on failure. |
1059 | */ | 1059 | */ |
1060 | int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, | 1060 | int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, |
1061 | unsigned char *buffer, int count) | 1061 | unsigned char *buffer, int count) |
@@ -1107,7 +1107,7 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, | |||
1107 | * the given size and updates the condition. | 1107 | * the given size and updates the condition. |
1108 | * Call after the transmission is finished. | 1108 | * Call after the transmission is finished. |
1109 | * | 1109 | * |
1110 | * Returns the advanced size if successful, or a negative error code on failure. | 1110 | * Return: The advanced size if successful, or a negative error code on failure. |
1111 | */ | 1111 | */ |
1112 | int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) | 1112 | int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) |
1113 | { | 1113 | { |
@@ -1140,7 +1140,7 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) | |||
1140 | * | 1140 | * |
1141 | * Copies data from the buffer to the device and advances the pointer. | 1141 | * Copies data from the buffer to the device and advances the pointer. |
1142 | * | 1142 | * |
1143 | * Returns the copied size if successful, or a negative error code on failure. | 1143 | * Return: The copied size if successful, or a negative error code on failure. |
1144 | */ | 1144 | */ |
1145 | int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, | 1145 | int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, |
1146 | unsigned char *buffer, int count) | 1146 | unsigned char *buffer, int count) |
@@ -1438,7 +1438,7 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, | |||
1438 | * Creates a new rawmidi instance. | 1438 | * Creates a new rawmidi instance. |
1439 | * Use snd_rawmidi_set_ops() to set the operators to the new instance. | 1439 | * Use snd_rawmidi_set_ops() to set the operators to the new instance. |
1440 | * | 1440 | * |
1441 | * Returns zero if successful, or a negative error code on failure. | 1441 | * Return: Zero if successful, or a negative error code on failure. |
1442 | */ | 1442 | */ |
1443 | int snd_rawmidi_new(struct snd_card *card, char *id, int device, | 1443 | int snd_rawmidi_new(struct snd_card *card, char *id, int device, |
1444 | int output_count, int input_count, | 1444 | int output_count, int input_count, |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 70ccdab74153..f002bd911dae 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -102,6 +102,9 @@ static void snd_request_other(int minor) | |||
102 | * This function increments the reference counter of the card instance | 102 | * This function increments the reference counter of the card instance |
103 | * if an associated instance with the given minor number and type is found. | 103 | * if an associated instance with the given minor number and type is found. |
104 | * The caller must call snd_card_unref() appropriately later. | 104 | * The caller must call snd_card_unref() appropriately later. |
105 | * | ||
106 | * Return: The user data pointer if the specified device is found. %NULL | ||
107 | * otherwise. | ||
105 | */ | 108 | */ |
106 | void *snd_lookup_minor_data(unsigned int minor, int type) | 109 | void *snd_lookup_minor_data(unsigned int minor, int type) |
107 | { | 110 | { |
@@ -261,7 +264,7 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) | |||
261 | * Registers an ALSA device file for the given card. | 264 | * Registers an ALSA device file for the given card. |
262 | * The operators have to be set in reg parameter. | 265 | * The operators have to be set in reg parameter. |
263 | * | 266 | * |
264 | * Returns zero if successful, or a negative error code on failure. | 267 | * Return: Zero if successful, or a negative error code on failure. |
265 | */ | 268 | */ |
266 | int snd_register_device_for_dev(int type, struct snd_card *card, int dev, | 269 | int snd_register_device_for_dev(int type, struct snd_card *card, int dev, |
267 | const struct file_operations *f_ops, | 270 | const struct file_operations *f_ops, |
@@ -339,7 +342,7 @@ static int find_snd_minor(int type, struct snd_card *card, int dev) | |||
339 | * Unregisters the device file already registered via | 342 | * Unregisters the device file already registered via |
340 | * snd_register_device(). | 343 | * snd_register_device(). |
341 | * | 344 | * |
342 | * Returns zero if sucecessful, or a negative error code on failure | 345 | * Return: Zero if successful, or a negative error code on failure. |
343 | */ | 346 | */ |
344 | int snd_unregister_device(int type, struct snd_card *card, int dev) | 347 | int snd_unregister_device(int type, struct snd_card *card, int dev) |
345 | { | 348 | { |
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 0097f3619faa..02f90b4f8b86 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
@@ -365,8 +365,7 @@ static void master_free(struct snd_kcontrol *kcontrol) | |||
365 | * @name: name string of the control element to create | 365 | * @name: name string of the control element to create |
366 | * @tlv: optional TLV int array for dB information | 366 | * @tlv: optional TLV int array for dB information |
367 | * | 367 | * |
368 | * Creates a virtual matster control with the given name string. | 368 | * Creates a virtual master control with the given name string. |
369 | * Returns the created control element, or NULL for errors (ENOMEM). | ||
370 | * | 369 | * |
371 | * After creating a vmaster element, you can add the slave controls | 370 | * After creating a vmaster element, you can add the slave controls |
372 | * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). | 371 | * via snd_ctl_add_slave() or snd_ctl_add_slave_uncached(). |
@@ -375,6 +374,8 @@ static void master_free(struct snd_kcontrol *kcontrol) | |||
375 | * for dB scale of the master control. It should be a single element | 374 | * for dB scale of the master control. It should be a single element |
376 | * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or | 375 | * with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or |
377 | * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. | 376 | * #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB. |
377 | * | ||
378 | * Return: The created control element, or %NULL for errors (ENOMEM). | ||
378 | */ | 379 | */ |
379 | struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, | 380 | struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, |
380 | const unsigned int *tlv) | 381 | const unsigned int *tlv) |
@@ -426,6 +427,8 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master); | |||
426 | * | 427 | * |
427 | * Adds the given hook to the vmaster control element so that it's called | 428 | * Adds the given hook to the vmaster control element so that it's called |
428 | * at each time when the value is changed. | 429 | * at each time when the value is changed. |
430 | * | ||
431 | * Return: Zero. | ||
429 | */ | 432 | */ |
430 | int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol, | 433 | int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol, |
431 | void (*hook)(void *private_data, int), | 434 | void (*hook)(void *private_data, int), |
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig index 7d02c322ed93..8545da99b183 100644 --- a/sound/drivers/Kconfig +++ b/sound/drivers/Kconfig | |||
@@ -87,7 +87,7 @@ config SND_ALOOP | |||
87 | configured number of substreams (see the pcm_substreams module | 87 | configured number of substreams (see the pcm_substreams module |
88 | parameter). | 88 | parameter). |
89 | 89 | ||
90 | The looback device allow time sychronization with an external | 90 | The loopback device allows time sychronization with an external |
91 | timing source using the time shift universal control (+-20% | 91 | timing source using the time shift universal control (+-20% |
92 | of system time). | 92 | of system time). |
93 | 93 | ||
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 64d534710b51..6f78de9c6fb6 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
@@ -325,7 +325,7 @@ static void params_change(struct snd_pcm_substream *substream) | |||
325 | struct loopback_pcm *dpcm = runtime->private_data; | 325 | struct loopback_pcm *dpcm = runtime->private_data; |
326 | struct loopback_cable *cable = dpcm->cable; | 326 | struct loopback_cable *cable = dpcm->cable; |
327 | 327 | ||
328 | cable->hw.formats = (1ULL << runtime->format); | 328 | cable->hw.formats = pcm_format_to_bits(runtime->format); |
329 | cable->hw.rate_min = runtime->rate; | 329 | cable->hw.rate_min = runtime->rate; |
330 | cable->hw.rate_max = runtime->rate; | 330 | cable->hw.rate_max = runtime->rate; |
331 | cable->hw.channels_min = runtime->channels; | 331 | cable->hw.channels_min = runtime->channels; |
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 4608c2ca43f8..e3a90d043f03 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
@@ -129,6 +129,8 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu) | |||
129 | * @dev_id: mpu401 instance | 129 | * @dev_id: mpu401 instance |
130 | * | 130 | * |
131 | * Processes the interrupt for MPU401-UART i/o. | 131 | * Processes the interrupt for MPU401-UART i/o. |
132 | * | ||
133 | * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise. | ||
132 | */ | 134 | */ |
133 | irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) | 135 | irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) |
134 | { | 136 | { |
@@ -148,6 +150,8 @@ EXPORT_SYMBOL(snd_mpu401_uart_interrupt); | |||
148 | * @dev_id: mpu401 instance | 150 | * @dev_id: mpu401 instance |
149 | * | 151 | * |
150 | * Processes the interrupt for MPU401-UART output. | 152 | * Processes the interrupt for MPU401-UART output. |
153 | * | ||
154 | * Return: %IRQ_HANDLED if the interrupt was handled. %IRQ_NONE otherwise. | ||
151 | */ | 155 | */ |
152 | irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) | 156 | irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) |
153 | { | 157 | { |
@@ -519,7 +523,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) | |||
519 | * not the mpu401 instance itself. To access to the mpu401 instance, | 523 | * not the mpu401 instance itself. To access to the mpu401 instance, |
520 | * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast). | 524 | * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast). |
521 | * | 525 | * |
522 | * Returns zero if successful, or a negative error code. | 526 | * Return: Zero if successful, or a negative error code. |
523 | */ | 527 | */ |
524 | int snd_mpu401_uart_new(struct snd_card *card, int device, | 528 | int snd_mpu401_uart_new(struct snd_card *card, int device, |
525 | unsigned short hardware, | 529 | unsigned short hardware, |
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c index bcc3e8e07122..a59c88818f48 100644 --- a/sound/oss/dmabuf.c +++ b/sound/oss/dmabuf.c | |||
@@ -114,7 +114,7 @@ static int sound_alloc_dmap(struct dma_buffparms *dmap) | |||
114 | } | 114 | } |
115 | } | 115 | } |
116 | dmap->raw_buf = start_addr; | 116 | dmap->raw_buf = start_addr; |
117 | dmap->raw_buf_phys = virt_to_bus(start_addr); | 117 | dmap->raw_buf_phys = dma_map_single(NULL, start_addr, dmap->buffsize, DMA_BIDIRECTIONAL); |
118 | 118 | ||
119 | for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++) | 119 | for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++) |
120 | SetPageReserved(page); | 120 | SetPageReserved(page); |
@@ -139,6 +139,7 @@ static void sound_free_dmap(struct dma_buffparms *dmap) | |||
139 | for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++) | 139 | for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++) |
140 | ClearPageReserved(page); | 140 | ClearPageReserved(page); |
141 | 141 | ||
142 | dma_unmap_single(NULL, dmap->raw_buf_phys, dmap->buffsize, DMA_BIDIRECTIONAL); | ||
142 | free_pages((unsigned long) dmap->raw_buf, sz); | 143 | free_pages((unsigned long) dmap->raw_buf, sz); |
143 | dmap->raw_buf = NULL; | 144 | dmap->raw_buf = NULL; |
144 | } | 145 | } |
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c index 7d42c5418d1b..851a1da46be1 100644 --- a/sound/oss/sb_common.c +++ b/sound/oss/sb_common.c | |||
@@ -626,13 +626,12 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_ | |||
626 | */ | 626 | */ |
627 | 627 | ||
628 | 628 | ||
629 | detected_devc = kmalloc(sizeof(sb_devc), GFP_KERNEL); | 629 | detected_devc = kmemdup(devc, sizeof(sb_devc), GFP_KERNEL); |
630 | if (detected_devc == NULL) | 630 | if (detected_devc == NULL) |
631 | { | 631 | { |
632 | printk(KERN_ERR "sb: Can't allocate memory for device information\n"); | 632 | printk(KERN_ERR "sb: Can't allocate memory for device information\n"); |
633 | return 0; | 633 | return 0; |
634 | } | 634 | } |
635 | memcpy(detected_devc, devc, sizeof(sb_devc)); | ||
636 | MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base)); | 635 | MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base)); |
637 | return 1; | 636 | return 1; |
638 | } | 637 | } |
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index 8e514a676a0d..5433c6f5eca2 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c | |||
@@ -352,23 +352,26 @@ int probe_uart401(struct address_info *hw_config, struct module *owner) | |||
352 | goto cleanup_irq; | 352 | goto cleanup_irq; |
353 | } | 353 | } |
354 | conf_printf(name, hw_config); | 354 | conf_printf(name, hw_config); |
355 | midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL); | 355 | midi_devs[devc->my_dev] = kmemdup(&uart401_operations, |
356 | sizeof(struct midi_operations), | ||
357 | GFP_KERNEL); | ||
356 | if (!midi_devs[devc->my_dev]) { | 358 | if (!midi_devs[devc->my_dev]) { |
357 | printk(KERN_ERR "uart401: Failed to allocate memory\n"); | 359 | printk(KERN_ERR "uart401: Failed to allocate memory\n"); |
358 | goto cleanup_unload_mididev; | 360 | goto cleanup_unload_mididev; |
359 | } | 361 | } |
360 | memcpy(midi_devs[devc->my_dev], &uart401_operations, sizeof(struct midi_operations)); | ||
361 | 362 | ||
362 | if (owner) | 363 | if (owner) |
363 | midi_devs[devc->my_dev]->owner = owner; | 364 | midi_devs[devc->my_dev]->owner = owner; |
364 | 365 | ||
365 | midi_devs[devc->my_dev]->devc = devc; | 366 | midi_devs[devc->my_dev]->devc = devc; |
366 | midi_devs[devc->my_dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL); | 367 | midi_devs[devc->my_dev]->converter = kmemdup(&std_midi_synth, |
368 | sizeof(struct synth_operations), | ||
369 | GFP_KERNEL); | ||
370 | |||
367 | if (!midi_devs[devc->my_dev]->converter) { | 371 | if (!midi_devs[devc->my_dev]->converter) { |
368 | printk(KERN_WARNING "uart401: Failed to allocate memory\n"); | 372 | printk(KERN_WARNING "uart401: Failed to allocate memory\n"); |
369 | goto cleanup_midi_devs; | 373 | goto cleanup_midi_devs; |
370 | } | 374 | } |
371 | memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations)); | ||
372 | strcpy(midi_devs[devc->my_dev]->info.name, name); | 375 | strcpy(midi_devs[devc->my_dev]->info.name, name); |
373 | midi_devs[devc->my_dev]->converter->id = "UART401"; | 376 | midi_devs[devc->my_dev]->converter->id = "UART401"; |
374 | midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev; | 377 | midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev; |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 8b0f99688303..d37c683cfd7a 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -299,7 +299,7 @@ EXPORT_SYMBOL(snd_ac97_write); | |||
299 | * Reads a value from the given register. This will invoke the read | 299 | * Reads a value from the given register. This will invoke the read |
300 | * callback directly after the register check. | 300 | * callback directly after the register check. |
301 | * | 301 | * |
302 | * Returns the read value. | 302 | * Return: The read value. |
303 | */ | 303 | */ |
304 | unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 304 | unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
305 | { | 305 | { |
@@ -352,7 +352,7 @@ EXPORT_SYMBOL(snd_ac97_write_cache); | |||
352 | * Compares the value with the register cache and updates the value | 352 | * Compares the value with the register cache and updates the value |
353 | * only when the value is changed. | 353 | * only when the value is changed. |
354 | * | 354 | * |
355 | * Returns 1 if the value is changed, 0 if no change, or a negative | 355 | * Return: 1 if the value is changed, 0 if no change, or a negative |
356 | * code on failure. | 356 | * code on failure. |
357 | */ | 357 | */ |
358 | int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value) | 358 | int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value) |
@@ -384,7 +384,7 @@ EXPORT_SYMBOL(snd_ac97_update); | |||
384 | * Updates the masked-bits on the given register only when the value | 384 | * Updates the masked-bits on the given register only when the value |
385 | * is changed. | 385 | * is changed. |
386 | * | 386 | * |
387 | * Returns 1 if the bits are changed, 0 if no change, or a negative | 387 | * Return: 1 if the bits are changed, 0 if no change, or a negative |
388 | * code on failure. | 388 | * code on failure. |
389 | */ | 389 | */ |
390 | int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value) | 390 | int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value) |
@@ -1836,7 +1836,7 @@ void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int m | |||
1836 | * snd_ac97_get_short_name - retrieve codec name | 1836 | * snd_ac97_get_short_name - retrieve codec name |
1837 | * @ac97: the codec instance | 1837 | * @ac97: the codec instance |
1838 | * | 1838 | * |
1839 | * Returns the short identifying name of the codec. | 1839 | * Return: The short identifying name of the codec. |
1840 | */ | 1840 | */ |
1841 | const char *snd_ac97_get_short_name(struct snd_ac97 *ac97) | 1841 | const char *snd_ac97_get_short_name(struct snd_ac97 *ac97) |
1842 | { | 1842 | { |
@@ -1910,7 +1910,7 @@ static int ac97_reset_wait(struct snd_ac97 *ac97, int timeout, int with_modem) | |||
1910 | * The AC97 bus instance is registered as a low-level device, so you don't | 1910 | * The AC97 bus instance is registered as a low-level device, so you don't |
1911 | * have to release it manually. | 1911 | * have to release it manually. |
1912 | * | 1912 | * |
1913 | * Returns zero if successful, or a negative error code on failure. | 1913 | * Return: Zero if successful, or a negative error code on failure. |
1914 | */ | 1914 | */ |
1915 | int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops, | 1915 | int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops, |
1916 | void *private_data, struct snd_ac97_bus **rbus) | 1916 | void *private_data, struct snd_ac97_bus **rbus) |
@@ -2006,7 +2006,7 @@ static void do_update_power(struct work_struct *work) | |||
2006 | * The ac97 instance is registered as a low-level device, so you don't | 2006 | * The ac97 instance is registered as a low-level device, so you don't |
2007 | * have to release it manually. | 2007 | * have to release it manually. |
2008 | * | 2008 | * |
2009 | * Returns zero if successful, or a negative error code on failure. | 2009 | * Return: Zero if successful, or a negative error code on failure. |
2010 | */ | 2010 | */ |
2011 | int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, struct snd_ac97 **rac97) | 2011 | int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, struct snd_ac97 **rac97) |
2012 | { | 2012 | { |
@@ -2373,6 +2373,8 @@ static struct ac97_power_reg power_regs[PWIDX_SIZE] = { | |||
2373 | * @powerup: non-zero when power up the part | 2373 | * @powerup: non-zero when power up the part |
2374 | * | 2374 | * |
2375 | * Update the AC97 powerdown register bits of the given part. | 2375 | * Update the AC97 powerdown register bits of the given part. |
2376 | * | ||
2377 | * Return: Zero. | ||
2376 | */ | 2378 | */ |
2377 | int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) | 2379 | int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup) |
2378 | { | 2380 | { |
@@ -2885,7 +2887,7 @@ static int apply_quirk_str(struct snd_ac97 *ac97, const char *typestr) | |||
2885 | * headphone (true line-out) control as "Master". | 2887 | * headphone (true line-out) control as "Master". |
2886 | * The quirk-list must be terminated with a zero-filled entry. | 2888 | * The quirk-list must be terminated with a zero-filled entry. |
2887 | * | 2889 | * |
2888 | * Returns zero if successful, or a negative error code on failure. | 2890 | * Return: Zero if successful, or a negative error code on failure. |
2889 | */ | 2891 | */ |
2890 | 2892 | ||
2891 | int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override) | 2893 | int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override) |
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index f1488fc176d5..eab0fc9ff2e0 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c | |||
@@ -253,7 +253,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) | |||
253 | * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF | 253 | * AC97_SPDIF is accepted as a pseudo register to modify the SPDIF |
254 | * status bits. | 254 | * status bits. |
255 | * | 255 | * |
256 | * Returns zero if successful, or a negative error code on failure. | 256 | * Return: Zero if successful, or a negative error code on failure. |
257 | */ | 257 | */ |
258 | int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate) | 258 | int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate) |
259 | { | 259 | { |
@@ -440,6 +440,8 @@ static unsigned int get_rates(struct ac97_pcm *pcm, unsigned int cidx, unsigned | |||
440 | * It assigns available AC97 slots for given PCMs. If none or only | 440 | * It assigns available AC97 slots for given PCMs. If none or only |
441 | * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members | 441 | * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members |
442 | * are reduced and might be zero. | 442 | * are reduced and might be zero. |
443 | * | ||
444 | * Return: Zero if successful, or a negative error code on failure. | ||
443 | */ | 445 | */ |
444 | int snd_ac97_pcm_assign(struct snd_ac97_bus *bus, | 446 | int snd_ac97_pcm_assign(struct snd_ac97_bus *bus, |
445 | unsigned short pcms_count, | 447 | unsigned short pcms_count, |
@@ -562,6 +564,8 @@ EXPORT_SYMBOL(snd_ac97_pcm_assign); | |||
562 | * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm | 564 | * @slots: a subset of allocated slots (snd_ac97_pcm_assign) for this pcm |
563 | * | 565 | * |
564 | * It locks the specified slots and sets the given rate to AC97 registers. | 566 | * It locks the specified slots and sets the given rate to AC97 registers. |
567 | * | ||
568 | * Return: Zero if successful, or a negative error code on failure. | ||
565 | */ | 569 | */ |
566 | int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate, | 570 | int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate, |
567 | enum ac97_pcm_cfg cfg, unsigned short slots) | 571 | enum ac97_pcm_cfg cfg, unsigned short slots) |
@@ -644,6 +648,8 @@ EXPORT_SYMBOL(snd_ac97_pcm_open); | |||
644 | * @pcm: the ac97 pcm instance | 648 | * @pcm: the ac97 pcm instance |
645 | * | 649 | * |
646 | * It frees the locked AC97 slots. | 650 | * It frees the locked AC97 slots. |
651 | * | ||
652 | * Return: Zero. | ||
647 | */ | 653 | */ |
648 | int snd_ac97_pcm_close(struct ac97_pcm *pcm) | 654 | int snd_ac97_pcm_close(struct ac97_pcm *pcm) |
649 | { | 655 | { |
@@ -718,6 +724,8 @@ static int double_rate_hw_constraint_channels(struct snd_pcm_hw_params *params, | |||
718 | * | 724 | * |
719 | * Installs the hardware constraint rules to prevent using double rates and | 725 | * Installs the hardware constraint rules to prevent using double rates and |
720 | * more than two channels at the same time. | 726 | * more than two channels at the same time. |
727 | * | ||
728 | * Return: Zero if successful, or a negative error code on failure. | ||
721 | */ | 729 | */ |
722 | int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime) | 730 | int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime) |
723 | { | 731 | { |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index e760af9d1fb6..53754f5edeb1 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -451,10 +451,10 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
451 | if (pci_dev) { | 451 | if (pci_dev) { |
452 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); | 452 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); |
453 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); | 453 | pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); |
454 | udelay(5000); | 454 | mdelay(5); |
455 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); | 455 | pci_read_config_dword(pci_dev, 0x7c, &dwVal); |
456 | pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff); | 456 | pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff); |
457 | udelay(5000); | 457 | mdelay(5); |
458 | } | 458 | } |
459 | 459 | ||
460 | pci_dev = codec->pci; | 460 | pci_dev = codec->pci; |
@@ -463,14 +463,14 @@ static int snd_ali_reset_5451(struct snd_ali *codec) | |||
463 | udelay(500); | 463 | udelay(500); |
464 | pci_read_config_dword(pci_dev, 0x44, &dwVal); | 464 | pci_read_config_dword(pci_dev, 0x44, &dwVal); |
465 | pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff); | 465 | pci_write_config_dword(pci_dev, 0x44, dwVal & 0xfffbffff); |
466 | udelay(5000); | 466 | mdelay(5); |
467 | 467 | ||
468 | wCount = 200; | 468 | wCount = 200; |
469 | while(wCount--) { | 469 | while(wCount--) { |
470 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); | 470 | wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); |
471 | if ((wReg & 0x000f) == 0x000f) | 471 | if ((wReg & 0x000f) == 0x000f) |
472 | return 0; | 472 | return 0; |
473 | udelay(5000); | 473 | mdelay(5); |
474 | } | 474 | } |
475 | 475 | ||
476 | /* non-fatal if you have a non PM capable codec */ | 476 | /* non-fatal if you have a non PM capable codec */ |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 0aabfedeecba..fbc17203613c 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -966,7 +966,7 @@ static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi, | |||
966 | if (!err) | 966 | if (!err) |
967 | err = hpi_outstream_query_format(h_stream, &hpi_format); | 967 | err = hpi_outstream_query_format(h_stream, &hpi_format); |
968 | if (!err && (hpi_to_alsa_formats[format] != -1)) | 968 | if (!err && (hpi_to_alsa_formats[format] != -1)) |
969 | formats |= (1ULL << hpi_to_alsa_formats[format]); | 969 | formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]); |
970 | } | 970 | } |
971 | return formats; | 971 | return formats; |
972 | } | 972 | } |
@@ -1141,8 +1141,8 @@ static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, | |||
1141 | format, sample_rate, 128000, 0); | 1141 | format, sample_rate, 128000, 0); |
1142 | if (!err) | 1142 | if (!err) |
1143 | err = hpi_instream_query_format(h_stream, &hpi_format); | 1143 | err = hpi_instream_query_format(h_stream, &hpi_format); |
1144 | if (!err) | 1144 | if (!err && (hpi_to_alsa_formats[format] != -1)) |
1145 | formats |= (1ULL << hpi_to_alsa_formats[format]); | 1145 | formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]); |
1146 | } | 1146 | } |
1147 | return formats; | 1147 | return formats; |
1148 | } | 1148 | } |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index e6b016693240..bdd888ec9a84 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -657,14 +657,14 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu) | |||
657 | return 0; | 657 | return 0; |
658 | } | 658 | } |
659 | 659 | ||
660 | static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu) | 660 | static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, |
661 | const struct firmware *fw_entry) | ||
661 | { | 662 | { |
662 | int n, i; | 663 | int n, i; |
663 | int reg; | 664 | int reg; |
664 | int value; | 665 | int value; |
665 | unsigned int write_post; | 666 | unsigned int write_post; |
666 | unsigned long flags; | 667 | unsigned long flags; |
667 | const struct firmware *fw_entry = emu->firmware; | ||
668 | 668 | ||
669 | if (!fw_entry) | 669 | if (!fw_entry) |
670 | return -EIO; | 670 | return -EIO; |
@@ -725,9 +725,34 @@ static int emu1010_firmware_thread(void *data) | |||
725 | /* Return to Audio Dock programming mode */ | 725 | /* Return to Audio Dock programming mode */ |
726 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); | 726 | snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); |
727 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK); | 727 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK); |
728 | err = snd_emu1010_load_firmware(emu); | 728 | |
729 | if (err != 0) | 729 | if (!emu->dock_fw) { |
730 | continue; | 730 | const char *filename = NULL; |
731 | switch (emu->card_capabilities->emu_model) { | ||
732 | case EMU_MODEL_EMU1010: | ||
733 | filename = DOCK_FILENAME; | ||
734 | break; | ||
735 | case EMU_MODEL_EMU1010B: | ||
736 | filename = MICRO_DOCK_FILENAME; | ||
737 | break; | ||
738 | case EMU_MODEL_EMU1616: | ||
739 | filename = MICRO_DOCK_FILENAME; | ||
740 | break; | ||
741 | } | ||
742 | if (filename) { | ||
743 | err = request_firmware(&emu->dock_fw, | ||
744 | filename, | ||
745 | &emu->pci->dev); | ||
746 | if (err) | ||
747 | continue; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | if (emu->dock_fw) { | ||
752 | err = snd_emu1010_load_firmware(emu, emu->dock_fw); | ||
753 | if (err) | ||
754 | continue; | ||
755 | } | ||
731 | 756 | ||
732 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); | 757 | snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); |
733 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ®); | 758 | snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ®); |
@@ -862,7 +887,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) | |||
862 | filename, emu->firmware->size); | 887 | filename, emu->firmware->size); |
863 | } | 888 | } |
864 | 889 | ||
865 | err = snd_emu1010_load_firmware(emu); | 890 | err = snd_emu1010_load_firmware(emu, emu->firmware); |
866 | if (err != 0) { | 891 | if (err != 0) { |
867 | snd_printk(KERN_INFO "emu1010: Loading Firmware failed\n"); | 892 | snd_printk(KERN_INFO "emu1010: Loading Firmware failed\n"); |
868 | return err; | 893 | return err; |
@@ -1253,6 +1278,8 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1253 | kthread_stop(emu->emu1010.firmware_thread); | 1278 | kthread_stop(emu->emu1010.firmware_thread); |
1254 | if (emu->firmware) | 1279 | if (emu->firmware) |
1255 | release_firmware(emu->firmware); | 1280 | release_firmware(emu->firmware); |
1281 | if (emu->dock_fw) | ||
1282 | release_firmware(emu->dock_fw); | ||
1256 | if (emu->irq >= 0) | 1283 | if (emu->irq >= 0) |
1257 | free_irq(emu->irq, emu); | 1284 | free_irq(emu->irq, emu); |
1258 | /* remove reserved page */ | 1285 | /* remove reserved page */ |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index a3ea76a4c9d2..7c11d46b84d3 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -119,6 +119,32 @@ static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin, | |||
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | static bool can_be_headset_mic(struct hda_codec *codec, | ||
123 | struct auto_pin_cfg_item *item, | ||
124 | int seq_number) | ||
125 | { | ||
126 | int attr; | ||
127 | unsigned int def_conf; | ||
128 | if (item->type != AUTO_PIN_MIC) | ||
129 | return false; | ||
130 | |||
131 | if (item->is_headset_mic || item->is_headphone_mic) | ||
132 | return false; /* Already assigned */ | ||
133 | |||
134 | def_conf = snd_hda_codec_get_pincfg(codec, item->pin); | ||
135 | attr = snd_hda_get_input_pin_attr(def_conf); | ||
136 | if (attr <= INPUT_PIN_ATTR_DOCK) | ||
137 | return false; | ||
138 | |||
139 | if (seq_number >= 0) { | ||
140 | int seq = get_defcfg_sequence(def_conf); | ||
141 | if (seq != seq_number) | ||
142 | return false; | ||
143 | } | ||
144 | |||
145 | return true; | ||
146 | } | ||
147 | |||
122 | /* | 148 | /* |
123 | * Parse all pin widgets and store the useful pin nids to cfg | 149 | * Parse all pin widgets and store the useful pin nids to cfg |
124 | * | 150 | * |
@@ -260,6 +286,38 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
260 | } | 286 | } |
261 | } | 287 | } |
262 | 288 | ||
289 | /* Find a pin that could be a headset or headphone mic */ | ||
290 | if (cond_flags & HDA_PINCFG_HEADSET_MIC || cond_flags & HDA_PINCFG_HEADPHONE_MIC) { | ||
291 | bool hsmic = !!(cond_flags & HDA_PINCFG_HEADSET_MIC); | ||
292 | bool hpmic = !!(cond_flags & HDA_PINCFG_HEADPHONE_MIC); | ||
293 | for (i = 0; (hsmic || hpmic) && (i < cfg->num_inputs); i++) | ||
294 | if (hsmic && can_be_headset_mic(codec, &cfg->inputs[i], 0xc)) { | ||
295 | cfg->inputs[i].is_headset_mic = 1; | ||
296 | hsmic = false; | ||
297 | } else if (hpmic && can_be_headset_mic(codec, &cfg->inputs[i], 0xd)) { | ||
298 | cfg->inputs[i].is_headphone_mic = 1; | ||
299 | hpmic = false; | ||
300 | } | ||
301 | |||
302 | /* If we didn't find our sequence number mark, fall back to any sequence number */ | ||
303 | for (i = 0; (hsmic || hpmic) && (i < cfg->num_inputs); i++) { | ||
304 | if (!can_be_headset_mic(codec, &cfg->inputs[i], -1)) | ||
305 | continue; | ||
306 | if (hsmic) { | ||
307 | cfg->inputs[i].is_headset_mic = 1; | ||
308 | hsmic = false; | ||
309 | } else if (hpmic) { | ||
310 | cfg->inputs[i].is_headphone_mic = 1; | ||
311 | hpmic = false; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | if (hsmic) | ||
316 | snd_printdd("Told to look for a headset mic, but didn't find any.\n"); | ||
317 | if (hpmic) | ||
318 | snd_printdd("Told to look for a headphone mic, but didn't find any.\n"); | ||
319 | } | ||
320 | |||
263 | /* FIX-UP: | 321 | /* FIX-UP: |
264 | * If no line-out is defined but multiple HPs are found, | 322 | * If no line-out is defined but multiple HPs are found, |
265 | * some of them might be the real line-outs. | 323 | * some of them might be the real line-outs. |
@@ -388,6 +446,7 @@ EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); | |||
388 | */ | 446 | */ |
389 | 447 | ||
390 | static const char *hda_get_input_pin_label(struct hda_codec *codec, | 448 | static const char *hda_get_input_pin_label(struct hda_codec *codec, |
449 | const struct auto_pin_cfg_item *item, | ||
391 | hda_nid_t pin, bool check_location) | 450 | hda_nid_t pin, bool check_location) |
392 | { | 451 | { |
393 | unsigned int def_conf; | 452 | unsigned int def_conf; |
@@ -400,6 +459,10 @@ static const char *hda_get_input_pin_label(struct hda_codec *codec, | |||
400 | 459 | ||
401 | switch (get_defcfg_device(def_conf)) { | 460 | switch (get_defcfg_device(def_conf)) { |
402 | case AC_JACK_MIC_IN: | 461 | case AC_JACK_MIC_IN: |
462 | if (item && item->is_headset_mic) | ||
463 | return "Headset Mic"; | ||
464 | if (item && item->is_headphone_mic) | ||
465 | return "Headphone Mic"; | ||
403 | if (!check_location) | 466 | if (!check_location) |
404 | return "Mic"; | 467 | return "Mic"; |
405 | attr = snd_hda_get_input_pin_attr(def_conf); | 468 | attr = snd_hda_get_input_pin_attr(def_conf); |
@@ -480,7 +543,8 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec, | |||
480 | has_multiple_pins = 1; | 543 | has_multiple_pins = 1; |
481 | if (has_multiple_pins && type == AUTO_PIN_MIC) | 544 | if (has_multiple_pins && type == AUTO_PIN_MIC) |
482 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); | 545 | has_multiple_pins &= check_mic_location_need(codec, cfg, input); |
483 | return hda_get_input_pin_label(codec, cfg->inputs[input].pin, | 546 | return hda_get_input_pin_label(codec, &cfg->inputs[input], |
547 | cfg->inputs[input].pin, | ||
484 | has_multiple_pins); | 548 | has_multiple_pins); |
485 | } | 549 | } |
486 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); | 550 | EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); |
@@ -649,7 +713,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
649 | } | 713 | } |
650 | } | 714 | } |
651 | if (!name) | 715 | if (!name) |
652 | name = hda_get_input_pin_label(codec, nid, true); | 716 | name = hda_get_input_pin_label(codec, NULL, nid, true); |
653 | break; | 717 | break; |
654 | } | 718 | } |
655 | if (!name) | 719 | if (!name) |
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index f74807138b49..e941f604f5e5 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h | |||
@@ -36,6 +36,8 @@ enum { | |||
36 | struct auto_pin_cfg_item { | 36 | struct auto_pin_cfg_item { |
37 | hda_nid_t pin; | 37 | hda_nid_t pin; |
38 | int type; | 38 | int type; |
39 | unsigned int is_headset_mic:1; | ||
40 | unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */ | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | struct auto_pin_cfg; | 43 | struct auto_pin_cfg; |
@@ -78,8 +80,10 @@ struct auto_pin_cfg { | |||
78 | }; | 80 | }; |
79 | 81 | ||
80 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ | 82 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ |
81 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ | 83 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ |
82 | #define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */ | 84 | #define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */ |
85 | #define HDA_PINCFG_HEADSET_MIC (1 << 2) /* Try to find headset mic; mark seq number as 0xc to trigger */ | ||
86 | #define HDA_PINCFG_HEADPHONE_MIC (1 << 3) /* Try to find headphone mic; mark seq number as 0xd to trigger */ | ||
83 | 87 | ||
84 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | 88 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, |
85 | struct auto_pin_cfg *cfg, | 89 | struct auto_pin_cfg *cfg, |
@@ -90,4 +94,25 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
90 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ | 94 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ |
91 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) | 95 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) |
92 | 96 | ||
97 | static inline int auto_cfg_hp_outs(const struct auto_pin_cfg *cfg) | ||
98 | { | ||
99 | return (cfg->line_out_type == AUTO_PIN_HP_OUT) ? | ||
100 | cfg->line_outs : cfg->hp_outs; | ||
101 | } | ||
102 | static inline const hda_nid_t *auto_cfg_hp_pins(const struct auto_pin_cfg *cfg) | ||
103 | { | ||
104 | return (cfg->line_out_type == AUTO_PIN_HP_OUT) ? | ||
105 | cfg->line_out_pins : cfg->hp_pins; | ||
106 | } | ||
107 | static inline int auto_cfg_speaker_outs(const struct auto_pin_cfg *cfg) | ||
108 | { | ||
109 | return (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) ? | ||
110 | cfg->line_outs : cfg->speaker_outs; | ||
111 | } | ||
112 | static inline const hda_nid_t *auto_cfg_speaker_pins(const struct auto_pin_cfg *cfg) | ||
113 | { | ||
114 | return (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) ? | ||
115 | cfg->line_out_pins : cfg->speaker_pins; | ||
116 | } | ||
117 | |||
93 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ | 118 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0849aac449f2..63c99090a4ec 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -39,13 +39,23 @@ static void snd_hda_generate_beep(struct work_struct *work) | |||
39 | struct hda_beep *beep = | 39 | struct hda_beep *beep = |
40 | container_of(work, struct hda_beep, beep_work); | 40 | container_of(work, struct hda_beep, beep_work); |
41 | struct hda_codec *codec = beep->codec; | 41 | struct hda_codec *codec = beep->codec; |
42 | int tone; | ||
42 | 43 | ||
43 | if (!beep->enabled) | 44 | if (!beep->enabled) |
44 | return; | 45 | return; |
45 | 46 | ||
47 | tone = beep->tone; | ||
48 | if (tone && !beep->playing) { | ||
49 | snd_hda_power_up(codec); | ||
50 | beep->playing = 1; | ||
51 | } | ||
46 | /* generate tone */ | 52 | /* generate tone */ |
47 | snd_hda_codec_write(codec, beep->nid, 0, | 53 | snd_hda_codec_write(codec, beep->nid, 0, |
48 | AC_VERB_SET_BEEP_CONTROL, beep->tone); | 54 | AC_VERB_SET_BEEP_CONTROL, tone); |
55 | if (!tone && beep->playing) { | ||
56 | beep->playing = 0; | ||
57 | snd_hda_power_down(codec); | ||
58 | } | ||
49 | } | 59 | } |
50 | 60 | ||
51 | /* (non-standard) Linear beep tone calculation for IDT/STAC codecs | 61 | /* (non-standard) Linear beep tone calculation for IDT/STAC codecs |
@@ -115,14 +125,23 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, | |||
115 | return 0; | 125 | return 0; |
116 | } | 126 | } |
117 | 127 | ||
128 | static void turn_off_beep(struct hda_beep *beep) | ||
129 | { | ||
130 | cancel_work_sync(&beep->beep_work); | ||
131 | if (beep->playing) { | ||
132 | /* turn off beep */ | ||
133 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
134 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
135 | beep->playing = 0; | ||
136 | snd_hda_power_down(beep->codec); | ||
137 | } | ||
138 | } | ||
139 | |||
118 | static void snd_hda_do_detach(struct hda_beep *beep) | 140 | static void snd_hda_do_detach(struct hda_beep *beep) |
119 | { | 141 | { |
120 | input_unregister_device(beep->dev); | 142 | input_unregister_device(beep->dev); |
121 | beep->dev = NULL; | 143 | beep->dev = NULL; |
122 | cancel_work_sync(&beep->beep_work); | 144 | turn_off_beep(beep); |
123 | /* turn off beep for sure */ | ||
124 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
125 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
126 | } | 145 | } |
127 | 146 | ||
128 | static int snd_hda_do_attach(struct hda_beep *beep) | 147 | static int snd_hda_do_attach(struct hda_beep *beep) |
@@ -170,12 +189,8 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | |||
170 | enable = !!enable; | 189 | enable = !!enable; |
171 | if (beep->enabled != enable) { | 190 | if (beep->enabled != enable) { |
172 | beep->enabled = enable; | 191 | beep->enabled = enable; |
173 | if (!enable) { | 192 | if (!enable) |
174 | cancel_work_sync(&beep->beep_work); | 193 | turn_off_beep(beep); |
175 | /* turn off beep */ | ||
176 | snd_hda_codec_write(beep->codec, beep->nid, 0, | ||
177 | AC_VERB_SET_BEEP_CONTROL, 0); | ||
178 | } | ||
179 | return 1; | 194 | return 1; |
180 | } | 195 | } |
181 | return 0; | 196 | return 0; |
@@ -198,7 +213,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
198 | snprintf(beep->phys, sizeof(beep->phys), | 213 | snprintf(beep->phys, sizeof(beep->phys), |
199 | "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); | 214 | "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); |
200 | /* enable linear scale */ | 215 | /* enable linear scale */ |
201 | snd_hda_codec_write(codec, nid, 0, | 216 | snd_hda_codec_write_cache(codec, nid, 0, |
202 | AC_VERB_SET_DIGI_CONVERT_2, 0x01); | 217 | AC_VERB_SET_DIGI_CONVERT_2, 0x01); |
203 | 218 | ||
204 | beep->nid = nid; | 219 | beep->nid = nid; |
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 4dc6933bc655..cb88464676b6 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -36,6 +36,7 @@ struct hda_beep { | |||
36 | hda_nid_t nid; | 36 | hda_nid_t nid; |
37 | unsigned int enabled:1; | 37 | unsigned int enabled:1; |
38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
39 | unsigned int playing:1; | ||
39 | struct work_struct beep_work; /* scheduled task for beep event */ | 40 | struct work_struct beep_work; /* scheduled task for beep event */ |
40 | struct mutex mutex; | 41 | struct mutex mutex; |
41 | }; | 42 | }; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4aba7646dd9c..6f9b64700f6e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1065,8 +1065,14 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list, | |||
1065 | { | 1065 | { |
1066 | struct hda_pincfg *pin; | 1066 | struct hda_pincfg *pin; |
1067 | 1067 | ||
1068 | /* the check below may be invalid when pins are added by a fixup | ||
1069 | * dynamically (e.g. via snd_hda_codec_update_widgets()), so disabled | ||
1070 | * for now | ||
1071 | */ | ||
1072 | /* | ||
1068 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | 1073 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) |
1069 | return -EINVAL; | 1074 | return -EINVAL; |
1075 | */ | ||
1070 | 1076 | ||
1071 | pin = look_up_pincfg(codec, list, nid); | 1077 | pin = look_up_pincfg(codec, list, nid); |
1072 | if (!pin) { | 1078 | if (!pin) { |
@@ -1300,8 +1306,6 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, | |||
1300 | 1306 | ||
1301 | static unsigned int hda_set_power_state(struct hda_codec *codec, | 1307 | static unsigned int hda_set_power_state(struct hda_codec *codec, |
1302 | unsigned int power_state); | 1308 | unsigned int power_state); |
1303 | static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid, | ||
1304 | unsigned int power_state); | ||
1305 | 1309 | ||
1306 | /** | 1310 | /** |
1307 | * snd_hda_codec_new - create a HDA codec | 1311 | * snd_hda_codec_new - create a HDA codec |
@@ -1422,7 +1426,6 @@ int snd_hda_codec_new(struct hda_bus *bus, | |||
1422 | #endif | 1426 | #endif |
1423 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, | 1427 | codec->epss = snd_hda_codec_get_supported_ps(codec, fg, |
1424 | AC_PWRST_EPSS); | 1428 | AC_PWRST_EPSS); |
1425 | codec->power_filter = default_power_filter; | ||
1426 | 1429 | ||
1427 | /* power-up all before initialization */ | 1430 | /* power-up all before initialization */ |
1428 | hda_set_power_state(codec, AC_PWRST_D0); | 1431 | hda_set_power_state(codec, AC_PWRST_D0); |
@@ -2787,6 +2790,11 @@ void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) | |||
2787 | { | 2790 | { |
2788 | if (!hook->hook || !hook->codec) | 2791 | if (!hook->hook || !hook->codec) |
2789 | return; | 2792 | return; |
2793 | /* don't call vmaster hook in the destructor since it might have | ||
2794 | * been already destroyed | ||
2795 | */ | ||
2796 | if (hook->codec->bus->shutdown) | ||
2797 | return; | ||
2790 | switch (hook->mute_mode) { | 2798 | switch (hook->mute_mode) { |
2791 | case HDA_VMUTE_FOLLOW_MASTER: | 2799 | case HDA_VMUTE_FOLLOW_MASTER: |
2792 | snd_ctl_sync_vmaster_hook(hook->sw_kctl); | 2800 | snd_ctl_sync_vmaster_hook(hook->sw_kctl); |
@@ -3770,8 +3778,9 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec, | |||
3770 | } | 3778 | } |
3771 | 3779 | ||
3772 | /* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */ | 3780 | /* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */ |
3773 | static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid, | 3781 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, |
3774 | unsigned int power_state) | 3782 | hda_nid_t nid, |
3783 | unsigned int power_state) | ||
3775 | { | 3784 | { |
3776 | if (power_state == AC_PWRST_D3 && | 3785 | if (power_state == AC_PWRST_D3 && |
3777 | get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && | 3786 | get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && |
@@ -3783,6 +3792,7 @@ static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid, | |||
3783 | } | 3792 | } |
3784 | return power_state; | 3793 | return power_state; |
3785 | } | 3794 | } |
3795 | EXPORT_SYMBOL_HDA(snd_hda_codec_eapd_power_filter); | ||
3786 | 3796 | ||
3787 | /* | 3797 | /* |
3788 | * set power state of the codec, and return the power state | 3798 | * set power state of the codec, and return the power state |
@@ -3827,8 +3837,8 @@ static void sync_power_up_states(struct hda_codec *codec) | |||
3827 | hda_nid_t nid = codec->start_nid; | 3837 | hda_nid_t nid = codec->start_nid; |
3828 | int i; | 3838 | int i; |
3829 | 3839 | ||
3830 | /* don't care if no or standard filter is used */ | 3840 | /* don't care if no filter is used */ |
3831 | if (!codec->power_filter || codec->power_filter == default_power_filter) | 3841 | if (!codec->power_filter) |
3832 | return; | 3842 | return; |
3833 | 3843 | ||
3834 | for (i = 0; i < codec->num_nodes; i++, nid++) { | 3844 | for (i = 0; i < codec->num_nodes; i++, nid++) { |
@@ -5546,14 +5556,12 @@ void *snd_array_new(struct snd_array *array) | |||
5546 | if (array->used >= array->alloced) { | 5556 | if (array->used >= array->alloced) { |
5547 | int num = array->alloced + array->alloc_align; | 5557 | int num = array->alloced + array->alloc_align; |
5548 | int size = (num + 1) * array->elem_size; | 5558 | int size = (num + 1) * array->elem_size; |
5549 | int oldsize = array->alloced * array->elem_size; | ||
5550 | void *nlist; | 5559 | void *nlist; |
5551 | if (snd_BUG_ON(num >= 4096)) | 5560 | if (snd_BUG_ON(num >= 4096)) |
5552 | return NULL; | 5561 | return NULL; |
5553 | nlist = krealloc(array->list, size, GFP_KERNEL); | 5562 | nlist = krealloc(array->list, size, GFP_KERNEL | __GFP_ZERO); |
5554 | if (!nlist) | 5563 | if (!nlist) |
5555 | return NULL; | 5564 | return NULL; |
5556 | memset(nlist + oldsize, 0, size - oldsize); | ||
5557 | array->list = nlist; | 5565 | array->list = nlist; |
5558 | array->alloced = num; | 5566 | array->alloced = num; |
5559 | } | 5567 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 23ca1722aff1..c93f9021f452 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -757,6 +757,9 @@ struct hda_pcm_ops { | |||
757 | struct snd_pcm_substream *substream); | 757 | struct snd_pcm_substream *substream); |
758 | int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, | 758 | int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, |
759 | struct snd_pcm_substream *substream); | 759 | struct snd_pcm_substream *substream); |
760 | unsigned int (*get_delay)(struct hda_pcm_stream *info, | ||
761 | struct hda_codec *codec, | ||
762 | struct snd_pcm_substream *substream); | ||
760 | }; | 763 | }; |
761 | 764 | ||
762 | /* PCM information for each substream */ | 765 | /* PCM information for each substream */ |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 2dbe767be16b..ac079f93c535 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_auto_parser.h" | 35 | #include "hda_auto_parser.h" |
36 | #include "hda_jack.h" | 36 | #include "hda_jack.h" |
37 | #include "hda_beep.h" | ||
37 | #include "hda_generic.h" | 38 | #include "hda_generic.h" |
38 | 39 | ||
39 | 40 | ||
@@ -150,15 +151,25 @@ static void parse_user_hints(struct hda_codec *codec) | |||
150 | val = snd_hda_get_bool_hint(codec, "add_stereo_mix_input"); | 151 | val = snd_hda_get_bool_hint(codec, "add_stereo_mix_input"); |
151 | if (val >= 0) | 152 | if (val >= 0) |
152 | spec->add_stereo_mix_input = !!val; | 153 | spec->add_stereo_mix_input = !!val; |
154 | /* the following two are just for compatibility */ | ||
153 | val = snd_hda_get_bool_hint(codec, "add_out_jack_modes"); | 155 | val = snd_hda_get_bool_hint(codec, "add_out_jack_modes"); |
154 | if (val >= 0) | 156 | if (val >= 0) |
155 | spec->add_out_jack_modes = !!val; | 157 | spec->add_jack_modes = !!val; |
156 | val = snd_hda_get_bool_hint(codec, "add_in_jack_modes"); | 158 | val = snd_hda_get_bool_hint(codec, "add_in_jack_modes"); |
157 | if (val >= 0) | 159 | if (val >= 0) |
158 | spec->add_in_jack_modes = !!val; | 160 | spec->add_jack_modes = !!val; |
161 | val = snd_hda_get_bool_hint(codec, "add_jack_modes"); | ||
162 | if (val >= 0) | ||
163 | spec->add_jack_modes = !!val; | ||
159 | val = snd_hda_get_bool_hint(codec, "power_down_unused"); | 164 | val = snd_hda_get_bool_hint(codec, "power_down_unused"); |
160 | if (val >= 0) | 165 | if (val >= 0) |
161 | spec->power_down_unused = !!val; | 166 | spec->power_down_unused = !!val; |
167 | val = snd_hda_get_bool_hint(codec, "add_hp_mic"); | ||
168 | if (val >= 0) | ||
169 | spec->hp_mic = !!val; | ||
170 | val = snd_hda_get_bool_hint(codec, "hp_mic_detect"); | ||
171 | if (val >= 0) | ||
172 | spec->suppress_hp_mic_detect = !val; | ||
162 | 173 | ||
163 | if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) | 174 | if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) |
164 | spec->mixer_nid = val; | 175 | spec->mixer_nid = val; |
@@ -996,7 +1007,7 @@ enum { | |||
996 | /* Primary DAC shared with main surrounds */ | 1007 | /* Primary DAC shared with main surrounds */ |
997 | BAD_SHARED_SURROUND = 0x100, | 1008 | BAD_SHARED_SURROUND = 0x100, |
998 | /* No independent HP possible */ | 1009 | /* No independent HP possible */ |
999 | BAD_NO_INDEP_HP = 0x40, | 1010 | BAD_NO_INDEP_HP = 0x10, |
1000 | /* Primary DAC shared with main CLFE */ | 1011 | /* Primary DAC shared with main CLFE */ |
1001 | BAD_SHARED_CLFE = 0x10, | 1012 | BAD_SHARED_CLFE = 0x10, |
1002 | /* Primary DAC shared with extra surrounds */ | 1013 | /* Primary DAC shared with extra surrounds */ |
@@ -1051,16 +1062,7 @@ static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path) | |||
1051 | return badness; | 1062 | return badness; |
1052 | } | 1063 | } |
1053 | 1064 | ||
1054 | struct badness_table { | 1065 | const struct badness_table hda_main_out_badness = { |
1055 | int no_primary_dac; /* no primary DAC */ | ||
1056 | int no_dac; /* no secondary DACs */ | ||
1057 | int shared_primary; /* primary DAC is shared with main output */ | ||
1058 | int shared_surr; /* secondary DAC shared with main or primary */ | ||
1059 | int shared_clfe; /* third DAC shared with main or primary */ | ||
1060 | int shared_surr_main; /* secondary DAC sahred with main/DAC0 */ | ||
1061 | }; | ||
1062 | |||
1063 | static struct badness_table main_out_badness = { | ||
1064 | .no_primary_dac = BAD_NO_PRIMARY_DAC, | 1066 | .no_primary_dac = BAD_NO_PRIMARY_DAC, |
1065 | .no_dac = BAD_NO_DAC, | 1067 | .no_dac = BAD_NO_DAC, |
1066 | .shared_primary = BAD_NO_PRIMARY_DAC, | 1068 | .shared_primary = BAD_NO_PRIMARY_DAC, |
@@ -1068,8 +1070,9 @@ static struct badness_table main_out_badness = { | |||
1068 | .shared_clfe = BAD_SHARED_CLFE, | 1070 | .shared_clfe = BAD_SHARED_CLFE, |
1069 | .shared_surr_main = BAD_SHARED_SURROUND, | 1071 | .shared_surr_main = BAD_SHARED_SURROUND, |
1070 | }; | 1072 | }; |
1073 | EXPORT_SYMBOL_HDA(hda_main_out_badness); | ||
1071 | 1074 | ||
1072 | static struct badness_table extra_out_badness = { | 1075 | const struct badness_table hda_extra_out_badness = { |
1073 | .no_primary_dac = BAD_NO_DAC, | 1076 | .no_primary_dac = BAD_NO_DAC, |
1074 | .no_dac = BAD_NO_DAC, | 1077 | .no_dac = BAD_NO_DAC, |
1075 | .shared_primary = BAD_NO_EXTRA_DAC, | 1078 | .shared_primary = BAD_NO_EXTRA_DAC, |
@@ -1077,6 +1080,7 @@ static struct badness_table extra_out_badness = { | |||
1077 | .shared_clfe = BAD_SHARED_EXTRA_SURROUND, | 1080 | .shared_clfe = BAD_SHARED_EXTRA_SURROUND, |
1078 | .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, | 1081 | .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, |
1079 | }; | 1082 | }; |
1083 | EXPORT_SYMBOL_HDA(hda_extra_out_badness); | ||
1080 | 1084 | ||
1081 | /* get the DAC of the primary output corresponding to the given array index */ | 1085 | /* get the DAC of the primary output corresponding to the given array index */ |
1082 | static hda_nid_t get_primary_out(struct hda_codec *codec, int idx) | 1086 | static hda_nid_t get_primary_out(struct hda_codec *codec, int idx) |
@@ -1367,22 +1371,25 @@ static int check_aamix_out_path(struct hda_codec *codec, int path_idx) | |||
1367 | { | 1371 | { |
1368 | struct hda_gen_spec *spec = codec->spec; | 1372 | struct hda_gen_spec *spec = codec->spec; |
1369 | struct nid_path *path; | 1373 | struct nid_path *path; |
1370 | hda_nid_t dac, pin; | 1374 | hda_nid_t path_dac, dac, pin; |
1371 | 1375 | ||
1372 | path = snd_hda_get_path_from_idx(codec, path_idx); | 1376 | path = snd_hda_get_path_from_idx(codec, path_idx); |
1373 | if (!path || !path->depth || | 1377 | if (!path || !path->depth || |
1374 | is_nid_contained(path, spec->mixer_nid)) | 1378 | is_nid_contained(path, spec->mixer_nid)) |
1375 | return 0; | 1379 | return 0; |
1376 | dac = path->path[0]; | 1380 | path_dac = path->path[0]; |
1381 | dac = spec->private_dac_nids[0]; | ||
1377 | pin = path->path[path->depth - 1]; | 1382 | pin = path->path[path->depth - 1]; |
1378 | path = snd_hda_add_new_path(codec, dac, pin, spec->mixer_nid); | 1383 | path = snd_hda_add_new_path(codec, dac, pin, spec->mixer_nid); |
1379 | if (!path) { | 1384 | if (!path) { |
1380 | if (dac != spec->multiout.dac_nids[0]) | 1385 | if (dac != path_dac) |
1381 | dac = spec->multiout.dac_nids[0]; | 1386 | dac = path_dac; |
1382 | else if (spec->multiout.hp_out_nid[0]) | 1387 | else if (spec->multiout.hp_out_nid[0]) |
1383 | dac = spec->multiout.hp_out_nid[0]; | 1388 | dac = spec->multiout.hp_out_nid[0]; |
1384 | else if (spec->multiout.extra_out_nid[0]) | 1389 | else if (spec->multiout.extra_out_nid[0]) |
1385 | dac = spec->multiout.extra_out_nid[0]; | 1390 | dac = spec->multiout.extra_out_nid[0]; |
1391 | else | ||
1392 | dac = 0; | ||
1386 | if (dac) | 1393 | if (dac) |
1387 | path = snd_hda_add_new_path(codec, dac, pin, | 1394 | path = snd_hda_add_new_path(codec, dac, pin, |
1388 | spec->mixer_nid); | 1395 | spec->mixer_nid); |
@@ -1507,7 +1514,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1507 | 1514 | ||
1508 | badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins, | 1515 | badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins, |
1509 | spec->private_dac_nids, spec->out_paths, | 1516 | spec->private_dac_nids, spec->out_paths, |
1510 | &main_out_badness); | 1517 | spec->main_out_badness); |
1511 | 1518 | ||
1512 | if (fill_mio_first && | 1519 | if (fill_mio_first && |
1513 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 1520 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
@@ -1522,7 +1529,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1522 | err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 1529 | err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
1523 | spec->multiout.hp_out_nid, | 1530 | spec->multiout.hp_out_nid, |
1524 | spec->hp_paths, | 1531 | spec->hp_paths, |
1525 | &extra_out_badness); | 1532 | spec->extra_out_badness); |
1526 | if (err < 0) | 1533 | if (err < 0) |
1527 | return err; | 1534 | return err; |
1528 | badness += err; | 1535 | badness += err; |
@@ -1532,7 +1539,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec, | |||
1532 | cfg->speaker_pins, | 1539 | cfg->speaker_pins, |
1533 | spec->multiout.extra_out_nid, | 1540 | spec->multiout.extra_out_nid, |
1534 | spec->speaker_paths, | 1541 | spec->speaker_paths, |
1535 | &extra_out_badness); | 1542 | spec->extra_out_badness); |
1536 | if (err < 0) | 1543 | if (err < 0) |
1537 | return err; | 1544 | return err; |
1538 | badness += err; | 1545 | badness += err; |
@@ -1926,6 +1933,17 @@ static int create_speaker_out_ctls(struct hda_codec *codec) | |||
1926 | * independent HP controls | 1933 | * independent HP controls |
1927 | */ | 1934 | */ |
1928 | 1935 | ||
1936 | /* update HP auto-mute state too */ | ||
1937 | static void update_hp_automute_hook(struct hda_codec *codec) | ||
1938 | { | ||
1939 | struct hda_gen_spec *spec = codec->spec; | ||
1940 | |||
1941 | if (spec->hp_automute_hook) | ||
1942 | spec->hp_automute_hook(codec, NULL); | ||
1943 | else | ||
1944 | snd_hda_gen_hp_automute(codec, NULL); | ||
1945 | } | ||
1946 | |||
1929 | static int indep_hp_info(struct snd_kcontrol *kcontrol, | 1947 | static int indep_hp_info(struct snd_kcontrol *kcontrol, |
1930 | struct snd_ctl_elem_info *uinfo) | 1948 | struct snd_ctl_elem_info *uinfo) |
1931 | { | 1949 | { |
@@ -1986,12 +2004,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, | |||
1986 | else | 2004 | else |
1987 | *dacp = spec->alt_dac_nid; | 2005 | *dacp = spec->alt_dac_nid; |
1988 | 2006 | ||
1989 | /* update HP auto-mute state too */ | 2007 | update_hp_automute_hook(codec); |
1990 | if (spec->hp_automute_hook) | ||
1991 | spec->hp_automute_hook(codec, NULL); | ||
1992 | else | ||
1993 | snd_hda_gen_hp_automute(codec, NULL); | ||
1994 | |||
1995 | ret = 1; | 2008 | ret = 1; |
1996 | } | 2009 | } |
1997 | unlock: | 2010 | unlock: |
@@ -2072,6 +2085,14 @@ get_multiio_path(struct hda_codec *codec, int idx) | |||
2072 | 2085 | ||
2073 | static void update_automute_all(struct hda_codec *codec); | 2086 | static void update_automute_all(struct hda_codec *codec); |
2074 | 2087 | ||
2088 | /* Default value to be passed as aamix argument for snd_hda_activate_path(); | ||
2089 | * used for output paths | ||
2090 | */ | ||
2091 | static bool aamix_default(struct hda_gen_spec *spec) | ||
2092 | { | ||
2093 | return !spec->have_aamix_ctl || spec->aamix_mode; | ||
2094 | } | ||
2095 | |||
2075 | static int set_multi_io(struct hda_codec *codec, int idx, bool output) | 2096 | static int set_multi_io(struct hda_codec *codec, int idx, bool output) |
2076 | { | 2097 | { |
2077 | struct hda_gen_spec *spec = codec->spec; | 2098 | struct hda_gen_spec *spec = codec->spec; |
@@ -2087,11 +2108,11 @@ static int set_multi_io(struct hda_codec *codec, int idx, bool output) | |||
2087 | 2108 | ||
2088 | if (output) { | 2109 | if (output) { |
2089 | set_pin_target(codec, nid, PIN_OUT, true); | 2110 | set_pin_target(codec, nid, PIN_OUT, true); |
2090 | snd_hda_activate_path(codec, path, true, true); | 2111 | snd_hda_activate_path(codec, path, true, aamix_default(spec)); |
2091 | set_pin_eapd(codec, nid, true); | 2112 | set_pin_eapd(codec, nid, true); |
2092 | } else { | 2113 | } else { |
2093 | set_pin_eapd(codec, nid, false); | 2114 | set_pin_eapd(codec, nid, false); |
2094 | snd_hda_activate_path(codec, path, false, true); | 2115 | snd_hda_activate_path(codec, path, false, aamix_default(spec)); |
2095 | set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true); | 2116 | set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true); |
2096 | path_power_down_sync(codec, path); | 2117 | path_power_down_sync(codec, path); |
2097 | } | 2118 | } |
@@ -2182,8 +2203,8 @@ static void update_aamix_paths(struct hda_codec *codec, bool do_mix, | |||
2182 | snd_hda_activate_path(codec, mix_path, true, true); | 2203 | snd_hda_activate_path(codec, mix_path, true, true); |
2183 | path_power_down_sync(codec, nomix_path); | 2204 | path_power_down_sync(codec, nomix_path); |
2184 | } else { | 2205 | } else { |
2185 | snd_hda_activate_path(codec, mix_path, false, true); | 2206 | snd_hda_activate_path(codec, mix_path, false, false); |
2186 | snd_hda_activate_path(codec, nomix_path, true, true); | 2207 | snd_hda_activate_path(codec, nomix_path, true, false); |
2187 | path_power_down_sync(codec, mix_path); | 2208 | path_power_down_sync(codec, mix_path); |
2188 | } | 2209 | } |
2189 | } | 2210 | } |
@@ -2240,63 +2261,95 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec) | |||
2240 | static void call_update_outputs(struct hda_codec *codec); | 2261 | static void call_update_outputs(struct hda_codec *codec); |
2241 | 2262 | ||
2242 | /* for shared I/O, change the pin-control accordingly */ | 2263 | /* for shared I/O, change the pin-control accordingly */ |
2243 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | 2264 | static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force) |
2244 | { | 2265 | { |
2245 | struct hda_gen_spec *spec = codec->spec; | 2266 | struct hda_gen_spec *spec = codec->spec; |
2267 | bool as_mic; | ||
2246 | unsigned int val; | 2268 | unsigned int val; |
2247 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | 2269 | hda_nid_t pin; |
2248 | /* NOTE: this assumes that there are only two inputs, the | ||
2249 | * first is the real internal mic and the second is HP/mic jack. | ||
2250 | */ | ||
2251 | 2270 | ||
2252 | val = snd_hda_get_default_vref(codec, pin); | 2271 | pin = spec->hp_mic_pin; |
2272 | as_mic = spec->cur_mux[adc_mux] == spec->hp_mic_mux_idx; | ||
2273 | |||
2274 | if (!force) { | ||
2275 | val = snd_hda_codec_get_pin_target(codec, pin); | ||
2276 | if (as_mic) { | ||
2277 | if (val & PIN_IN) | ||
2278 | return; | ||
2279 | } else { | ||
2280 | if (val & PIN_OUT) | ||
2281 | return; | ||
2282 | } | ||
2283 | } | ||
2253 | 2284 | ||
2254 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | 2285 | val = snd_hda_get_default_vref(codec, pin); |
2255 | instead, as suggested by Realtek */ | 2286 | /* if the HP pin doesn't support VREF and the codec driver gives an |
2287 | * alternative pin, set up the VREF on that pin instead | ||
2288 | */ | ||
2256 | if (val == AC_PINCTL_VREF_HIZ && spec->shared_mic_vref_pin) { | 2289 | if (val == AC_PINCTL_VREF_HIZ && spec->shared_mic_vref_pin) { |
2257 | const hda_nid_t vref_pin = spec->shared_mic_vref_pin; | 2290 | const hda_nid_t vref_pin = spec->shared_mic_vref_pin; |
2258 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | 2291 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); |
2259 | if (vref_val != AC_PINCTL_VREF_HIZ) | 2292 | if (vref_val != AC_PINCTL_VREF_HIZ) |
2260 | snd_hda_set_pin_ctl_cache(codec, vref_pin, | 2293 | snd_hda_set_pin_ctl_cache(codec, vref_pin, |
2261 | PIN_IN | (set_as_mic ? vref_val : 0)); | 2294 | PIN_IN | (as_mic ? vref_val : 0)); |
2262 | } | 2295 | } |
2263 | 2296 | ||
2264 | val = set_as_mic ? val | PIN_IN : PIN_HP; | 2297 | if (!spec->hp_mic_jack_modes) { |
2265 | set_pin_target(codec, pin, val, true); | 2298 | if (as_mic) |
2266 | 2299 | val |= PIN_IN; | |
2267 | spec->automute_speaker = !set_as_mic; | 2300 | else |
2268 | call_update_outputs(codec); | 2301 | val = PIN_HP; |
2302 | set_pin_target(codec, pin, val, true); | ||
2303 | update_hp_automute_hook(codec); | ||
2304 | } | ||
2269 | } | 2305 | } |
2270 | 2306 | ||
2271 | /* create a shared input with the headphone out */ | 2307 | /* create a shared input with the headphone out */ |
2272 | static int create_shared_input(struct hda_codec *codec) | 2308 | static int create_hp_mic(struct hda_codec *codec) |
2273 | { | 2309 | { |
2274 | struct hda_gen_spec *spec = codec->spec; | 2310 | struct hda_gen_spec *spec = codec->spec; |
2275 | struct auto_pin_cfg *cfg = &spec->autocfg; | 2311 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2276 | unsigned int defcfg; | 2312 | unsigned int defcfg; |
2277 | hda_nid_t nid; | 2313 | hda_nid_t nid; |
2278 | 2314 | ||
2279 | /* only one internal input pin? */ | 2315 | if (!spec->hp_mic) { |
2280 | if (cfg->num_inputs != 1) | 2316 | if (spec->suppress_hp_mic_detect) |
2281 | return 0; | 2317 | return 0; |
2282 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); | 2318 | /* automatic detection: only if no input or a single internal |
2283 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | 2319 | * input pin is found, try to detect the shared hp/mic |
2320 | */ | ||
2321 | if (cfg->num_inputs > 1) | ||
2322 | return 0; | ||
2323 | else if (cfg->num_inputs == 1) { | ||
2324 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); | ||
2325 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | ||
2326 | return 0; | ||
2327 | } | ||
2328 | } | ||
2329 | |||
2330 | spec->hp_mic = 0; /* clear once */ | ||
2331 | if (cfg->num_inputs >= AUTO_CFG_MAX_INS) | ||
2284 | return 0; | 2332 | return 0; |
2285 | 2333 | ||
2286 | if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | 2334 | nid = 0; |
2287 | nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ | 2335 | if (cfg->line_out_type == AUTO_PIN_HP_OUT && cfg->line_outs > 0) |
2288 | else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) | 2336 | nid = cfg->line_out_pins[0]; |
2289 | nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ | 2337 | else if (cfg->hp_outs > 0) |
2290 | else | 2338 | nid = cfg->hp_pins[0]; |
2291 | return 0; /* both not available */ | 2339 | if (!nid) |
2340 | return 0; | ||
2292 | 2341 | ||
2293 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) | 2342 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) |
2294 | return 0; /* no input */ | 2343 | return 0; /* no input */ |
2295 | 2344 | ||
2296 | cfg->inputs[1].pin = nid; | 2345 | cfg->inputs[cfg->num_inputs].pin = nid; |
2297 | cfg->inputs[1].type = AUTO_PIN_MIC; | 2346 | cfg->inputs[cfg->num_inputs].type = AUTO_PIN_MIC; |
2298 | cfg->num_inputs = 2; | 2347 | cfg->inputs[cfg->num_inputs].is_headphone_mic = 1; |
2299 | spec->shared_mic_hp = 1; | 2348 | cfg->num_inputs++; |
2349 | spec->hp_mic = 1; | ||
2350 | spec->hp_mic_pin = nid; | ||
2351 | /* we can't handle auto-mic together with HP-mic */ | ||
2352 | spec->suppress_auto_mic = 1; | ||
2300 | snd_printdd("hda-codec: Enable shared I/O jack on NID 0x%x\n", nid); | 2353 | snd_printdd("hda-codec: Enable shared I/O jack on NID 0x%x\n", nid); |
2301 | return 0; | 2354 | return 0; |
2302 | } | 2355 | } |
@@ -2304,13 +2357,17 @@ static int create_shared_input(struct hda_codec *codec) | |||
2304 | /* | 2357 | /* |
2305 | * output jack mode | 2358 | * output jack mode |
2306 | */ | 2359 | */ |
2360 | |||
2361 | static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin); | ||
2362 | |||
2363 | static const char * const out_jack_texts[] = { | ||
2364 | "Line Out", "Headphone Out", | ||
2365 | }; | ||
2366 | |||
2307 | static int out_jack_mode_info(struct snd_kcontrol *kcontrol, | 2367 | static int out_jack_mode_info(struct snd_kcontrol *kcontrol, |
2308 | struct snd_ctl_elem_info *uinfo) | 2368 | struct snd_ctl_elem_info *uinfo) |
2309 | { | 2369 | { |
2310 | static const char * const texts[] = { | 2370 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, out_jack_texts); |
2311 | "Line Out", "Headphone Out", | ||
2312 | }; | ||
2313 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts); | ||
2314 | } | 2371 | } |
2315 | 2372 | ||
2316 | static int out_jack_mode_get(struct snd_kcontrol *kcontrol, | 2373 | static int out_jack_mode_get(struct snd_kcontrol *kcontrol, |
@@ -2372,6 +2429,17 @@ static void get_jack_mode_name(struct hda_codec *codec, hda_nid_t pin, | |||
2372 | ; | 2429 | ; |
2373 | } | 2430 | } |
2374 | 2431 | ||
2432 | static int get_out_jack_num_items(struct hda_codec *codec, hda_nid_t pin) | ||
2433 | { | ||
2434 | struct hda_gen_spec *spec = codec->spec; | ||
2435 | if (spec->add_jack_modes) { | ||
2436 | unsigned int pincap = snd_hda_query_pin_caps(codec, pin); | ||
2437 | if ((pincap & AC_PINCAP_OUT) && (pincap & AC_PINCAP_HP_DRV)) | ||
2438 | return 2; | ||
2439 | } | ||
2440 | return 1; | ||
2441 | } | ||
2442 | |||
2375 | static int create_out_jack_modes(struct hda_codec *codec, int num_pins, | 2443 | static int create_out_jack_modes(struct hda_codec *codec, int num_pins, |
2376 | hda_nid_t *pins) | 2444 | hda_nid_t *pins) |
2377 | { | 2445 | { |
@@ -2380,8 +2448,13 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins, | |||
2380 | 2448 | ||
2381 | for (i = 0; i < num_pins; i++) { | 2449 | for (i = 0; i < num_pins; i++) { |
2382 | hda_nid_t pin = pins[i]; | 2450 | hda_nid_t pin = pins[i]; |
2383 | unsigned int pincap = snd_hda_query_pin_caps(codec, pin); | 2451 | if (pin == spec->hp_mic_pin) { |
2384 | if ((pincap & AC_PINCAP_OUT) && (pincap & AC_PINCAP_HP_DRV)) { | 2452 | int ret = create_hp_mic_jack_mode(codec, pin); |
2453 | if (ret < 0) | ||
2454 | return ret; | ||
2455 | continue; | ||
2456 | } | ||
2457 | if (get_out_jack_num_items(codec, pin) > 1) { | ||
2385 | struct snd_kcontrol_new *knew; | 2458 | struct snd_kcontrol_new *knew; |
2386 | char name[44]; | 2459 | char name[44]; |
2387 | get_jack_mode_name(codec, pin, name, sizeof(name)); | 2460 | get_jack_mode_name(codec, pin, name, sizeof(name)); |
@@ -2502,12 +2575,24 @@ static const struct snd_kcontrol_new in_jack_mode_enum = { | |||
2502 | .put = in_jack_mode_put, | 2575 | .put = in_jack_mode_put, |
2503 | }; | 2576 | }; |
2504 | 2577 | ||
2578 | static int get_in_jack_num_items(struct hda_codec *codec, hda_nid_t pin) | ||
2579 | { | ||
2580 | struct hda_gen_spec *spec = codec->spec; | ||
2581 | int nitems = 0; | ||
2582 | if (spec->add_jack_modes) | ||
2583 | nitems = hweight32(get_vref_caps(codec, pin)); | ||
2584 | return nitems ? nitems : 1; | ||
2585 | } | ||
2586 | |||
2505 | static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin) | 2587 | static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin) |
2506 | { | 2588 | { |
2507 | struct hda_gen_spec *spec = codec->spec; | 2589 | struct hda_gen_spec *spec = codec->spec; |
2508 | unsigned int defcfg; | ||
2509 | struct snd_kcontrol_new *knew; | 2590 | struct snd_kcontrol_new *knew; |
2510 | char name[44]; | 2591 | char name[44]; |
2592 | unsigned int defcfg; | ||
2593 | |||
2594 | if (pin == spec->hp_mic_pin) | ||
2595 | return 0; /* already done in create_out_jack_mode() */ | ||
2511 | 2596 | ||
2512 | /* no jack mode for fixed pins */ | 2597 | /* no jack mode for fixed pins */ |
2513 | defcfg = snd_hda_codec_get_pincfg(codec, pin); | 2598 | defcfg = snd_hda_codec_get_pincfg(codec, pin); |
@@ -2515,7 +2600,7 @@ static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin) | |||
2515 | return 0; | 2600 | return 0; |
2516 | 2601 | ||
2517 | /* no multiple vref caps? */ | 2602 | /* no multiple vref caps? */ |
2518 | if (hweight32(get_vref_caps(codec, pin)) <= 1) | 2603 | if (get_in_jack_num_items(codec, pin) <= 1) |
2519 | return 0; | 2604 | return 0; |
2520 | 2605 | ||
2521 | get_jack_mode_name(codec, pin, name, sizeof(name)); | 2606 | get_jack_mode_name(codec, pin, name, sizeof(name)); |
@@ -2526,6 +2611,132 @@ static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin) | |||
2526 | return 0; | 2611 | return 0; |
2527 | } | 2612 | } |
2528 | 2613 | ||
2614 | /* | ||
2615 | * HP/mic shared jack mode | ||
2616 | */ | ||
2617 | static int hp_mic_jack_mode_info(struct snd_kcontrol *kcontrol, | ||
2618 | struct snd_ctl_elem_info *uinfo) | ||
2619 | { | ||
2620 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2621 | hda_nid_t nid = kcontrol->private_value; | ||
2622 | int out_jacks = get_out_jack_num_items(codec, nid); | ||
2623 | int in_jacks = get_in_jack_num_items(codec, nid); | ||
2624 | const char *text = NULL; | ||
2625 | int idx; | ||
2626 | |||
2627 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2628 | uinfo->count = 1; | ||
2629 | uinfo->value.enumerated.items = out_jacks + in_jacks; | ||
2630 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2631 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2632 | idx = uinfo->value.enumerated.item; | ||
2633 | if (idx < out_jacks) { | ||
2634 | if (out_jacks > 1) | ||
2635 | text = out_jack_texts[idx]; | ||
2636 | else | ||
2637 | text = "Headphone Out"; | ||
2638 | } else { | ||
2639 | idx -= out_jacks; | ||
2640 | if (in_jacks > 1) { | ||
2641 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2642 | text = vref_texts[get_vref_idx(vref_caps, idx)]; | ||
2643 | } else | ||
2644 | text = "Mic In"; | ||
2645 | } | ||
2646 | |||
2647 | strcpy(uinfo->value.enumerated.name, text); | ||
2648 | return 0; | ||
2649 | } | ||
2650 | |||
2651 | static int get_cur_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t nid) | ||
2652 | { | ||
2653 | int out_jacks = get_out_jack_num_items(codec, nid); | ||
2654 | int in_jacks = get_in_jack_num_items(codec, nid); | ||
2655 | unsigned int val = snd_hda_codec_get_pin_target(codec, nid); | ||
2656 | int idx = 0; | ||
2657 | |||
2658 | if (val & PIN_OUT) { | ||
2659 | if (out_jacks > 1 && val == PIN_HP) | ||
2660 | idx = 1; | ||
2661 | } else if (val & PIN_IN) { | ||
2662 | idx = out_jacks; | ||
2663 | if (in_jacks > 1) { | ||
2664 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2665 | val &= AC_PINCTL_VREFEN; | ||
2666 | idx += cvt_from_vref_idx(vref_caps, val); | ||
2667 | } | ||
2668 | } | ||
2669 | return idx; | ||
2670 | } | ||
2671 | |||
2672 | static int hp_mic_jack_mode_get(struct snd_kcontrol *kcontrol, | ||
2673 | struct snd_ctl_elem_value *ucontrol) | ||
2674 | { | ||
2675 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2676 | hda_nid_t nid = kcontrol->private_value; | ||
2677 | ucontrol->value.enumerated.item[0] = | ||
2678 | get_cur_hp_mic_jack_mode(codec, nid); | ||
2679 | return 0; | ||
2680 | } | ||
2681 | |||
2682 | static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, | ||
2683 | struct snd_ctl_elem_value *ucontrol) | ||
2684 | { | ||
2685 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2686 | hda_nid_t nid = kcontrol->private_value; | ||
2687 | int out_jacks = get_out_jack_num_items(codec, nid); | ||
2688 | int in_jacks = get_in_jack_num_items(codec, nid); | ||
2689 | unsigned int val, oldval, idx; | ||
2690 | |||
2691 | oldval = get_cur_hp_mic_jack_mode(codec, nid); | ||
2692 | idx = ucontrol->value.enumerated.item[0]; | ||
2693 | if (oldval == idx) | ||
2694 | return 0; | ||
2695 | |||
2696 | if (idx < out_jacks) { | ||
2697 | if (out_jacks > 1) | ||
2698 | val = idx ? PIN_HP : PIN_OUT; | ||
2699 | else | ||
2700 | val = PIN_HP; | ||
2701 | } else { | ||
2702 | idx -= out_jacks; | ||
2703 | if (in_jacks > 1) { | ||
2704 | unsigned int vref_caps = get_vref_caps(codec, nid); | ||
2705 | val = snd_hda_codec_get_pin_target(codec, nid); | ||
2706 | val &= ~(AC_PINCTL_VREFEN | PIN_HP); | ||
2707 | val |= get_vref_idx(vref_caps, idx) | PIN_IN; | ||
2708 | } else | ||
2709 | val = snd_hda_get_default_vref(codec, nid); | ||
2710 | } | ||
2711 | snd_hda_set_pin_ctl_cache(codec, nid, val); | ||
2712 | update_hp_automute_hook(codec); | ||
2713 | |||
2714 | return 1; | ||
2715 | } | ||
2716 | |||
2717 | static const struct snd_kcontrol_new hp_mic_jack_mode_enum = { | ||
2718 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2719 | .info = hp_mic_jack_mode_info, | ||
2720 | .get = hp_mic_jack_mode_get, | ||
2721 | .put = hp_mic_jack_mode_put, | ||
2722 | }; | ||
2723 | |||
2724 | static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin) | ||
2725 | { | ||
2726 | struct hda_gen_spec *spec = codec->spec; | ||
2727 | struct snd_kcontrol_new *knew; | ||
2728 | |||
2729 | if (get_out_jack_num_items(codec, pin) <= 1 && | ||
2730 | get_in_jack_num_items(codec, pin) <= 1) | ||
2731 | return 0; /* no need */ | ||
2732 | knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode", | ||
2733 | &hp_mic_jack_mode_enum); | ||
2734 | if (!knew) | ||
2735 | return -ENOMEM; | ||
2736 | knew->private_value = pin; | ||
2737 | spec->hp_mic_jack_modes = 1; | ||
2738 | return 0; | ||
2739 | } | ||
2529 | 2740 | ||
2530 | /* | 2741 | /* |
2531 | * Parse input paths | 2742 | * Parse input paths |
@@ -2648,7 +2859,6 @@ static int check_dyn_adc_switch(struct hda_codec *codec) | |||
2648 | unsigned int ok_bits; | 2859 | unsigned int ok_bits; |
2649 | int i, n, nums; | 2860 | int i, n, nums; |
2650 | 2861 | ||
2651 | again: | ||
2652 | nums = 0; | 2862 | nums = 0; |
2653 | ok_bits = 0; | 2863 | ok_bits = 0; |
2654 | for (n = 0; n < spec->num_adc_nids; n++) { | 2864 | for (n = 0; n < spec->num_adc_nids; n++) { |
@@ -2663,12 +2873,6 @@ static int check_dyn_adc_switch(struct hda_codec *codec) | |||
2663 | } | 2873 | } |
2664 | 2874 | ||
2665 | if (!ok_bits) { | 2875 | if (!ok_bits) { |
2666 | if (spec->shared_mic_hp) { | ||
2667 | spec->shared_mic_hp = 0; | ||
2668 | imux->num_items = 1; | ||
2669 | goto again; | ||
2670 | } | ||
2671 | |||
2672 | /* check whether ADC-switch is possible */ | 2876 | /* check whether ADC-switch is possible */ |
2673 | for (i = 0; i < imux->num_items; i++) { | 2877 | for (i = 0; i < imux->num_items; i++) { |
2674 | for (n = 0; n < spec->num_adc_nids; n++) { | 2878 | for (n = 0; n < spec->num_adc_nids; n++) { |
@@ -2701,7 +2905,8 @@ static int check_dyn_adc_switch(struct hda_codec *codec) | |||
2701 | spec->num_adc_nids = nums; | 2905 | spec->num_adc_nids = nums; |
2702 | } | 2906 | } |
2703 | 2907 | ||
2704 | if (imux->num_items == 1 || spec->shared_mic_hp) { | 2908 | if (imux->num_items == 1 || |
2909 | (imux->num_items == 2 && spec->hp_mic)) { | ||
2705 | snd_printdd("hda-codec: reducing to a single ADC\n"); | 2910 | snd_printdd("hda-codec: reducing to a single ADC\n"); |
2706 | spec->num_adc_nids = 1; /* reduce to a single ADC */ | 2911 | spec->num_adc_nids = 1; /* reduce to a single ADC */ |
2707 | } | 2912 | } |
@@ -2738,6 +2943,8 @@ static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin, | |||
2738 | snd_hda_get_path_idx(codec, path); | 2943 | snd_hda_get_path_idx(codec, path); |
2739 | 2944 | ||
2740 | if (!imux_added) { | 2945 | if (!imux_added) { |
2946 | if (spec->hp_mic_pin == pin) | ||
2947 | spec->hp_mic_mux_idx = imux->num_items; | ||
2741 | spec->imux_pins[imux->num_items] = pin; | 2948 | spec->imux_pins[imux->num_items] = pin; |
2742 | snd_hda_add_imux_item(imux, label, cfg_idx, NULL); | 2949 | snd_hda_add_imux_item(imux, label, cfg_idx, NULL); |
2743 | imux_added = true; | 2950 | imux_added = true; |
@@ -2812,7 +3019,8 @@ static int create_input_ctls(struct hda_codec *codec) | |||
2812 | val = PIN_IN; | 3019 | val = PIN_IN; |
2813 | if (cfg->inputs[i].type == AUTO_PIN_MIC) | 3020 | if (cfg->inputs[i].type == AUTO_PIN_MIC) |
2814 | val |= snd_hda_get_default_vref(codec, pin); | 3021 | val |= snd_hda_get_default_vref(codec, pin); |
2815 | set_pin_target(codec, pin, val, false); | 3022 | if (pin != spec->hp_mic_pin) |
3023 | set_pin_target(codec, pin, val, false); | ||
2816 | 3024 | ||
2817 | if (mixer) { | 3025 | if (mixer) { |
2818 | if (is_reachable_path(codec, pin, mixer)) { | 3026 | if (is_reachable_path(codec, pin, mixer)) { |
@@ -2830,7 +3038,7 @@ static int create_input_ctls(struct hda_codec *codec) | |||
2830 | if (err < 0) | 3038 | if (err < 0) |
2831 | return err; | 3039 | return err; |
2832 | 3040 | ||
2833 | if (spec->add_in_jack_modes) { | 3041 | if (spec->add_jack_modes) { |
2834 | err = create_in_jack_mode(codec, pin); | 3042 | err = create_in_jack_mode(codec, pin); |
2835 | if (err < 0) | 3043 | if (err < 0) |
2836 | return err; | 3044 | return err; |
@@ -3462,8 +3670,8 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
3462 | 3670 | ||
3463 | spec->cur_mux[adc_idx] = idx; | 3671 | spec->cur_mux[adc_idx] = idx; |
3464 | 3672 | ||
3465 | if (spec->shared_mic_hp) | 3673 | if (spec->hp_mic) |
3466 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); | 3674 | update_hp_mic(codec, adc_idx, false); |
3467 | 3675 | ||
3468 | if (spec->dyn_adc_switch) | 3676 | if (spec->dyn_adc_switch) |
3469 | dyn_adc_pcm_resetup(codec, idx); | 3677 | dyn_adc_pcm_resetup(codec, idx); |
@@ -3511,18 +3719,21 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
3511 | 3719 | ||
3512 | for (i = 0; i < num_pins; i++) { | 3720 | for (i = 0; i < num_pins; i++) { |
3513 | hda_nid_t nid = pins[i]; | 3721 | hda_nid_t nid = pins[i]; |
3514 | unsigned int val; | 3722 | unsigned int val, oldval; |
3515 | if (!nid) | 3723 | if (!nid) |
3516 | break; | 3724 | break; |
3725 | oldval = snd_hda_codec_get_pin_target(codec, nid); | ||
3726 | if (oldval & PIN_IN) | ||
3727 | continue; /* no mute for inputs */ | ||
3517 | /* don't reset VREF value in case it's controlling | 3728 | /* don't reset VREF value in case it's controlling |
3518 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | 3729 | * the amp (see alc861_fixup_asus_amp_vref_0f()) |
3519 | */ | 3730 | */ |
3520 | if (spec->keep_vref_in_automute) | 3731 | if (spec->keep_vref_in_automute) |
3521 | val = snd_hda_codec_get_pin_target(codec, nid) & ~PIN_HP; | 3732 | val = oldval & ~PIN_HP; |
3522 | else | 3733 | else |
3523 | val = 0; | 3734 | val = 0; |
3524 | if (!mute) | 3735 | if (!mute) |
3525 | val |= snd_hda_codec_get_pin_target(codec, nid); | 3736 | val |= oldval; |
3526 | /* here we call update_pin_ctl() so that the pinctl is changed | 3737 | /* here we call update_pin_ctl() so that the pinctl is changed |
3527 | * without changing the pinctl target value; | 3738 | * without changing the pinctl target value; |
3528 | * the original target value will be still referred at the | 3739 | * the original target value will be still referred at the |
@@ -3543,8 +3754,7 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec) | |||
3543 | * in general, HP pins/amps control should be enabled in all cases, | 3754 | * in general, HP pins/amps control should be enabled in all cases, |
3544 | * but currently set only for master_mute, just to be safe | 3755 | * but currently set only for master_mute, just to be safe |
3545 | */ | 3756 | */ |
3546 | if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ | 3757 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
3547 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
3548 | spec->autocfg.hp_pins, spec->master_mute); | 3758 | spec->autocfg.hp_pins, spec->master_mute); |
3549 | 3759 | ||
3550 | if (!spec->automute_speaker) | 3760 | if (!spec->automute_speaker) |
@@ -3649,10 +3859,7 @@ static void update_automute_all(struct hda_codec *codec) | |||
3649 | { | 3859 | { |
3650 | struct hda_gen_spec *spec = codec->spec; | 3860 | struct hda_gen_spec *spec = codec->spec; |
3651 | 3861 | ||
3652 | if (spec->hp_automute_hook) | 3862 | update_hp_automute_hook(codec); |
3653 | spec->hp_automute_hook(codec, NULL); | ||
3654 | else | ||
3655 | snd_hda_gen_hp_automute(codec, NULL); | ||
3656 | if (spec->line_automute_hook) | 3863 | if (spec->line_automute_hook) |
3657 | spec->line_automute_hook(codec, NULL); | 3864 | spec->line_automute_hook(codec, NULL); |
3658 | else | 3865 | else |
@@ -3978,6 +4185,11 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
3978 | cfg = &spec->autocfg; | 4185 | cfg = &spec->autocfg; |
3979 | } | 4186 | } |
3980 | 4187 | ||
4188 | if (!spec->main_out_badness) | ||
4189 | spec->main_out_badness = &hda_main_out_badness; | ||
4190 | if (!spec->extra_out_badness) | ||
4191 | spec->extra_out_badness = &hda_extra_out_badness; | ||
4192 | |||
3981 | fill_all_dac_nids(codec); | 4193 | fill_all_dac_nids(codec); |
3982 | 4194 | ||
3983 | if (!cfg->line_outs) { | 4195 | if (!cfg->line_outs) { |
@@ -4024,7 +4236,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4024 | err = create_loopback_mixing_ctl(codec); | 4236 | err = create_loopback_mixing_ctl(codec); |
4025 | if (err < 0) | 4237 | if (err < 0) |
4026 | return err; | 4238 | return err; |
4027 | err = create_shared_input(codec); | 4239 | err = create_hp_mic(codec); |
4028 | if (err < 0) | 4240 | if (err < 0) |
4029 | return err; | 4241 | return err; |
4030 | err = create_input_ctls(codec); | 4242 | err = create_input_ctls(codec); |
@@ -4050,11 +4262,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4050 | if (err < 0) | 4262 | if (err < 0) |
4051 | return err; | 4263 | return err; |
4052 | 4264 | ||
4053 | if (!spec->shared_mic_hp) { | 4265 | err = check_auto_mic_availability(codec); |
4054 | err = check_auto_mic_availability(codec); | 4266 | if (err < 0) |
4055 | if (err < 0) | 4267 | return err; |
4056 | return err; | ||
4057 | } | ||
4058 | 4268 | ||
4059 | err = create_capture_mixers(codec); | 4269 | err = create_capture_mixers(codec); |
4060 | if (err < 0) | 4270 | if (err < 0) |
@@ -4064,7 +4274,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4064 | if (err < 0) | 4274 | if (err < 0) |
4065 | return err; | 4275 | return err; |
4066 | 4276 | ||
4067 | if (spec->add_out_jack_modes) { | 4277 | if (spec->add_jack_modes) { |
4068 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 4278 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
4069 | err = create_out_jack_modes(codec, cfg->line_outs, | 4279 | err = create_out_jack_modes(codec, cfg->line_outs, |
4070 | cfg->line_out_pins); | 4280 | cfg->line_out_pins); |
@@ -4085,6 +4295,12 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, | |||
4085 | if (spec->power_down_unused) | 4295 | if (spec->power_down_unused) |
4086 | codec->power_filter = snd_hda_gen_path_power_filter; | 4296 | codec->power_filter = snd_hda_gen_path_power_filter; |
4087 | 4297 | ||
4298 | if (!spec->no_analog && spec->beep_nid) { | ||
4299 | err = snd_hda_attach_beep_device(codec, spec->beep_nid); | ||
4300 | if (err < 0) | ||
4301 | return err; | ||
4302 | } | ||
4303 | |||
4088 | return 1; | 4304 | return 1; |
4089 | } | 4305 | } |
4090 | EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config); | 4306 | EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config); |
@@ -4161,17 +4377,6 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) | |||
4161 | 4377 | ||
4162 | free_kctls(spec); /* no longer needed */ | 4378 | free_kctls(spec); /* no longer needed */ |
4163 | 4379 | ||
4164 | if (spec->shared_mic_hp) { | ||
4165 | int err; | ||
4166 | int nid = spec->autocfg.inputs[1].pin; | ||
4167 | err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); | ||
4168 | if (err < 0) | ||
4169 | return err; | ||
4170 | err = snd_hda_jack_detect_enable(codec, nid, 0); | ||
4171 | if (err < 0) | ||
4172 | return err; | ||
4173 | } | ||
4174 | |||
4175 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 4380 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
4176 | if (err < 0) | 4381 | if (err < 0) |
4177 | return err; | 4382 | return err; |
@@ -4729,7 +4934,8 @@ static void set_output_and_unmute(struct hda_codec *codec, int path_idx) | |||
4729 | return; | 4934 | return; |
4730 | pin = path->path[path->depth - 1]; | 4935 | pin = path->path[path->depth - 1]; |
4731 | restore_pin_ctl(codec, pin); | 4936 | restore_pin_ctl(codec, pin); |
4732 | snd_hda_activate_path(codec, path, path->active, true); | 4937 | snd_hda_activate_path(codec, path, path->active, |
4938 | aamix_default(codec->spec)); | ||
4733 | set_pin_eapd(codec, pin, path->active); | 4939 | set_pin_eapd(codec, pin, path->active); |
4734 | } | 4940 | } |
4735 | 4941 | ||
@@ -4779,7 +4985,8 @@ static void init_multi_io(struct hda_codec *codec) | |||
4779 | if (!spec->multi_io[i].ctl_in) | 4985 | if (!spec->multi_io[i].ctl_in) |
4780 | spec->multi_io[i].ctl_in = | 4986 | spec->multi_io[i].ctl_in = |
4781 | snd_hda_codec_get_pin_target(codec, pin); | 4987 | snd_hda_codec_get_pin_target(codec, pin); |
4782 | snd_hda_activate_path(codec, path, path->active, true); | 4988 | snd_hda_activate_path(codec, path, path->active, |
4989 | aamix_default(spec)); | ||
4783 | } | 4990 | } |
4784 | } | 4991 | } |
4785 | 4992 | ||
@@ -4826,11 +5033,10 @@ static void init_input_src(struct hda_codec *codec) | |||
4826 | snd_hda_activate_path(codec, path, active, false); | 5033 | snd_hda_activate_path(codec, path, active, false); |
4827 | } | 5034 | } |
4828 | } | 5035 | } |
5036 | if (spec->hp_mic) | ||
5037 | update_hp_mic(codec, c, true); | ||
4829 | } | 5038 | } |
4830 | 5039 | ||
4831 | if (spec->shared_mic_hp) | ||
4832 | update_shared_mic_hp(codec, spec->cur_mux[0]); | ||
4833 | |||
4834 | if (spec->cap_sync_hook) | 5040 | if (spec->cap_sync_hook) |
4835 | spec->cap_sync_hook(codec, NULL); | 5041 | spec->cap_sync_hook(codec, NULL); |
4836 | } | 5042 | } |
@@ -4911,6 +5117,7 @@ EXPORT_SYMBOL_HDA(snd_hda_gen_init); | |||
4911 | */ | 5117 | */ |
4912 | void snd_hda_gen_free(struct hda_codec *codec) | 5118 | void snd_hda_gen_free(struct hda_codec *codec) |
4913 | { | 5119 | { |
5120 | snd_hda_detach_beep_device(codec); | ||
4914 | snd_hda_gen_spec_free(codec->spec); | 5121 | snd_hda_gen_spec_free(codec->spec); |
4915 | kfree(codec->spec); | 5122 | kfree(codec->spec); |
4916 | codec->spec = NULL; | 5123 | codec->spec = NULL; |
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 009b57be96d3..54e665160379 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h | |||
@@ -76,6 +76,19 @@ enum { | |||
76 | HDA_GEN_PCM_ACT_CLOSE, | 76 | HDA_GEN_PCM_ACT_CLOSE, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* DAC assignment badness table */ | ||
80 | struct badness_table { | ||
81 | int no_primary_dac; /* no primary DAC */ | ||
82 | int no_dac; /* no secondary DACs */ | ||
83 | int shared_primary; /* primary DAC is shared with main output */ | ||
84 | int shared_surr; /* secondary DAC shared with main or primary */ | ||
85 | int shared_clfe; /* third DAC shared with main or primary */ | ||
86 | int shared_surr_main; /* secondary DAC sahred with main/DAC0 */ | ||
87 | }; | ||
88 | |||
89 | extern const struct badness_table hda_main_out_badness; | ||
90 | extern const struct badness_table hda_extra_out_badness; | ||
91 | |||
79 | struct hda_gen_spec { | 92 | struct hda_gen_spec { |
80 | char stream_name_analog[32]; /* analog PCM stream */ | 93 | char stream_name_analog[32]; /* analog PCM stream */ |
81 | const struct hda_pcm_stream *stream_analog_playback; | 94 | const struct hda_pcm_stream *stream_analog_playback; |
@@ -145,7 +158,10 @@ struct hda_gen_spec { | |||
145 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 158 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
146 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; | 159 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; |
147 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; | 160 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; |
161 | /* shared hp/mic */ | ||
148 | hda_nid_t shared_mic_vref_pin; | 162 | hda_nid_t shared_mic_vref_pin; |
163 | hda_nid_t hp_mic_pin; | ||
164 | int hp_mic_mux_idx; | ||
149 | 165 | ||
150 | /* DAC/ADC lists */ | 166 | /* DAC/ADC lists */ |
151 | int num_all_dacs; | 167 | int num_all_dacs; |
@@ -200,7 +216,8 @@ struct hda_gen_spec { | |||
200 | 216 | ||
201 | /* other parse behavior flags */ | 217 | /* other parse behavior flags */ |
202 | unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */ | 218 | unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */ |
203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 219 | unsigned int hp_mic:1; /* Allow HP as a mic-in */ |
220 | unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */ | ||
204 | unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ | 221 | unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ |
205 | unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ | 222 | unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ |
206 | unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ | 223 | unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ |
@@ -209,8 +226,7 @@ struct hda_gen_spec { | |||
209 | unsigned int indep_hp:1; /* independent HP supported */ | 226 | unsigned int indep_hp:1; /* independent HP supported */ |
210 | unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ | 227 | unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ |
211 | unsigned int add_stereo_mix_input:1; /* add aamix as a capture src */ | 228 | unsigned int add_stereo_mix_input:1; /* add aamix as a capture src */ |
212 | unsigned int add_out_jack_modes:1; /* add output jack mode enum ctls */ | 229 | unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */ |
213 | unsigned int add_in_jack_modes:1; /* add input jack mode enum ctls */ | ||
214 | unsigned int power_down_unused:1; /* power down unused widgets */ | 230 | unsigned int power_down_unused:1; /* power down unused widgets */ |
215 | 231 | ||
216 | /* other internal flags */ | 232 | /* other internal flags */ |
@@ -218,10 +234,18 @@ struct hda_gen_spec { | |||
218 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ | 234 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ |
219 | unsigned int indep_hp_enabled:1; /* independent HP enabled */ | 235 | unsigned int indep_hp_enabled:1; /* independent HP enabled */ |
220 | unsigned int have_aamix_ctl:1; | 236 | unsigned int have_aamix_ctl:1; |
237 | unsigned int hp_mic_jack_modes:1; | ||
238 | |||
239 | /* badness tables for output path evaluations */ | ||
240 | const struct badness_table *main_out_badness; | ||
241 | const struct badness_table *extra_out_badness; | ||
221 | 242 | ||
222 | /* loopback mixing mode */ | 243 | /* loopback mixing mode */ |
223 | bool aamix_mode; | 244 | bool aamix_mode; |
224 | 245 | ||
246 | /* digital beep */ | ||
247 | hda_nid_t beep_nid; | ||
248 | |||
225 | /* for virtual master */ | 249 | /* for virtual master */ |
226 | hda_nid_t vmaster_nid; | 250 | hda_nid_t vmaster_nid; |
227 | unsigned int vmaster_tlv[4]; | 251 | unsigned int vmaster_tlv[4]; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bcd40ee488e3..7b213d589ef6 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1889,6 +1889,26 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream, | |||
1889 | tc->cycle_last = last; | 1889 | tc->cycle_last = last; |
1890 | } | 1890 | } |
1891 | 1891 | ||
1892 | static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, | ||
1893 | u64 nsec) | ||
1894 | { | ||
1895 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
1896 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | ||
1897 | u64 codec_frames, codec_nsecs; | ||
1898 | |||
1899 | if (!hinfo->ops.get_delay) | ||
1900 | return nsec; | ||
1901 | |||
1902 | codec_frames = hinfo->ops.get_delay(hinfo, apcm->codec, substream); | ||
1903 | codec_nsecs = div_u64(codec_frames * 1000000000LL, | ||
1904 | substream->runtime->rate); | ||
1905 | |||
1906 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
1907 | return nsec + codec_nsecs; | ||
1908 | |||
1909 | return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0; | ||
1910 | } | ||
1911 | |||
1892 | static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream, | 1912 | static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream, |
1893 | struct timespec *ts) | 1913 | struct timespec *ts) |
1894 | { | 1914 | { |
@@ -1897,6 +1917,7 @@ static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream, | |||
1897 | 1917 | ||
1898 | nsec = timecounter_read(&azx_dev->azx_tc); | 1918 | nsec = timecounter_read(&azx_dev->azx_tc); |
1899 | nsec = div_u64(nsec, 3); /* can be optimized */ | 1919 | nsec = div_u64(nsec, 3); /* can be optimized */ |
1920 | nsec = azx_adjust_codec_delay(substream, nsec); | ||
1900 | 1921 | ||
1901 | *ts = ns_to_timespec(nsec); | 1922 | *ts = ns_to_timespec(nsec); |
1902 | 1923 | ||
@@ -2349,8 +2370,11 @@ static unsigned int azx_get_position(struct azx *chip, | |||
2349 | struct azx_dev *azx_dev, | 2370 | struct azx_dev *azx_dev, |
2350 | bool with_check) | 2371 | bool with_check) |
2351 | { | 2372 | { |
2373 | struct snd_pcm_substream *substream = azx_dev->substream; | ||
2374 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
2352 | unsigned int pos; | 2375 | unsigned int pos; |
2353 | int stream = azx_dev->substream->stream; | 2376 | int stream = substream->stream; |
2377 | struct hda_pcm_stream *hinfo = apcm->hinfo[stream]; | ||
2354 | int delay = 0; | 2378 | int delay = 0; |
2355 | 2379 | ||
2356 | switch (chip->position_fix[stream]) { | 2380 | switch (chip->position_fix[stream]) { |
@@ -2381,7 +2405,7 @@ static unsigned int azx_get_position(struct azx *chip, | |||
2381 | pos = 0; | 2405 | pos = 0; |
2382 | 2406 | ||
2383 | /* calculate runtime delay from LPIB */ | 2407 | /* calculate runtime delay from LPIB */ |
2384 | if (azx_dev->substream->runtime && | 2408 | if (substream->runtime && |
2385 | chip->position_fix[stream] == POS_FIX_POSBUF && | 2409 | chip->position_fix[stream] == POS_FIX_POSBUF && |
2386 | (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { | 2410 | (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { |
2387 | unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); | 2411 | unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); |
@@ -2399,9 +2423,16 @@ static unsigned int azx_get_position(struct azx *chip, | |||
2399 | delay = 0; | 2423 | delay = 0; |
2400 | chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; | 2424 | chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; |
2401 | } | 2425 | } |
2402 | azx_dev->substream->runtime->delay = | 2426 | delay = bytes_to_frames(substream->runtime, delay); |
2403 | bytes_to_frames(azx_dev->substream->runtime, delay); | ||
2404 | } | 2427 | } |
2428 | |||
2429 | if (substream->runtime) { | ||
2430 | if (hinfo->ops.get_delay) | ||
2431 | delay += hinfo->ops.get_delay(hinfo, apcm->codec, | ||
2432 | substream); | ||
2433 | substream->runtime->delay = delay; | ||
2434 | } | ||
2435 | |||
2405 | trace_azx_get_position(chip, azx_dev, pos, delay); | 2436 | trace_azx_get_position(chip, azx_dev, pos, delay); |
2406 | return pos; | 2437 | return pos; |
2407 | } | 2438 | } |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 1d035efeff4f..9e0a95288f46 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -394,7 +394,8 @@ static int get_unique_index(struct hda_codec *codec, const char *name, int idx) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 396 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
397 | const struct auto_pin_cfg *cfg) | 397 | const struct auto_pin_cfg *cfg, |
398 | const char *base_name) | ||
398 | { | 399 | { |
399 | unsigned int def_conf, conn; | 400 | unsigned int def_conf, conn; |
400 | char name[44]; | 401 | char name[44]; |
@@ -410,7 +411,11 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
410 | phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || | 411 | phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || |
411 | !is_jack_detectable(codec, nid); | 412 | !is_jack_detectable(codec, nid); |
412 | 413 | ||
413 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | 414 | if (base_name) { |
415 | strlcpy(name, base_name, sizeof(name)); | ||
416 | idx = 0; | ||
417 | } else | ||
418 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | ||
414 | if (phantom_jack) | 419 | if (phantom_jack) |
415 | /* Example final name: "Internal Mic Phantom Jack" */ | 420 | /* Example final name: "Internal Mic Phantom Jack" */ |
416 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); | 421 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); |
@@ -433,39 +438,51 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
433 | const hda_nid_t *p; | 438 | const hda_nid_t *p; |
434 | int i, err; | 439 | int i, err; |
435 | 440 | ||
441 | for (i = 0; i < cfg->num_inputs; i++) { | ||
442 | /* If we have headphone mics; make sure they get the right name | ||
443 | before grabbed by output pins */ | ||
444 | if (cfg->inputs[i].is_headphone_mic) { | ||
445 | if (auto_cfg_hp_outs(cfg) == 1) | ||
446 | err = add_jack_kctl(codec, auto_cfg_hp_pins(cfg)[0], | ||
447 | cfg, "Headphone Mic"); | ||
448 | else | ||
449 | err = add_jack_kctl(codec, cfg->inputs[i].pin, | ||
450 | cfg, "Headphone Mic"); | ||
451 | } else | ||
452 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, | ||
453 | NULL); | ||
454 | if (err < 0) | ||
455 | return err; | ||
456 | } | ||
457 | |||
436 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 458 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
437 | err = add_jack_kctl(codec, *p, cfg); | 459 | err = add_jack_kctl(codec, *p, cfg, NULL); |
438 | if (err < 0) | 460 | if (err < 0) |
439 | return err; | 461 | return err; |
440 | } | 462 | } |
441 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 463 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
442 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 464 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
443 | break; | 465 | break; |
444 | err = add_jack_kctl(codec, *p, cfg); | 466 | err = add_jack_kctl(codec, *p, cfg, NULL); |
445 | if (err < 0) | 467 | if (err < 0) |
446 | return err; | 468 | return err; |
447 | } | 469 | } |
448 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 470 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
449 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 471 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
450 | break; | 472 | break; |
451 | err = add_jack_kctl(codec, *p, cfg); | 473 | err = add_jack_kctl(codec, *p, cfg, NULL); |
452 | if (err < 0) | ||
453 | return err; | ||
454 | } | ||
455 | for (i = 0; i < cfg->num_inputs; i++) { | ||
456 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); | ||
457 | if (err < 0) | 474 | if (err < 0) |
458 | return err; | 475 | return err; |
459 | } | 476 | } |
460 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 477 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
461 | err = add_jack_kctl(codec, *p, cfg); | 478 | err = add_jack_kctl(codec, *p, cfg, NULL); |
462 | if (err < 0) | 479 | if (err < 0) |
463 | return err; | 480 | return err; |
464 | } | 481 | } |
465 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); | 482 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, NULL); |
466 | if (err < 0) | 483 | if (err < 0) |
467 | return err; | 484 | return err; |
468 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); | 485 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, NULL); |
469 | if (err < 0) | 486 | if (err < 0) |
470 | return err; | 487 | return err; |
471 | return 0; | 488 | return 0; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 83b7486c8eff..e0bf7534fa1f 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -670,6 +670,10 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
670 | return (state != target_state); | 670 | return (state != target_state); |
671 | } | 671 | } |
672 | 672 | ||
673 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, | ||
674 | hda_nid_t nid, | ||
675 | unsigned int power_state); | ||
676 | |||
673 | /* | 677 | /* |
674 | * AMP control callbacks | 678 | * AMP control callbacks |
675 | */ | 679 | */ |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index df8014b27596..977b0d878dae 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -43,7 +43,6 @@ struct ad198x_spec { | |||
43 | hda_nid_t eapd_nid; | 43 | hda_nid_t eapd_nid; |
44 | 44 | ||
45 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 45 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
46 | hda_nid_t beep_dev_nid; | ||
47 | 46 | ||
48 | #ifdef ENABLE_AD_STATIC_QUIRKS | 47 | #ifdef ENABLE_AD_STATIC_QUIRKS |
49 | const struct snd_kcontrol_new *mixers[6]; | 48 | const struct snd_kcontrol_new *mixers[6]; |
@@ -609,7 +608,7 @@ static const struct hda_codec_ops ad198x_auto_patch_ops = { | |||
609 | .build_controls = ad198x_auto_build_controls, | 608 | .build_controls = ad198x_auto_build_controls, |
610 | .build_pcms = snd_hda_gen_build_pcms, | 609 | .build_pcms = snd_hda_gen_build_pcms, |
611 | .init = snd_hda_gen_init, | 610 | .init = snd_hda_gen_init, |
612 | .free = ad198x_free, | 611 | .free = snd_hda_gen_free, |
613 | .unsol_event = snd_hda_jack_unsol_event, | 612 | .unsol_event = snd_hda_jack_unsol_event, |
614 | #ifdef CONFIG_PM | 613 | #ifdef CONFIG_PM |
615 | .check_power_status = snd_hda_gen_check_power_status, | 614 | .check_power_status = snd_hda_gen_check_power_status, |
@@ -638,12 +637,6 @@ static int ad198x_parse_auto_config(struct hda_codec *codec) | |||
638 | if (err < 0) | 637 | if (err < 0) |
639 | return err; | 638 | return err; |
640 | 639 | ||
641 | if (spec->beep_dev_nid) { | ||
642 | err = snd_hda_attach_beep_device(codec, spec->beep_dev_nid); | ||
643 | if (err < 0) | ||
644 | return err; | ||
645 | } | ||
646 | |||
647 | codec->patch_ops = ad198x_auto_patch_ops; | 640 | codec->patch_ops = ad198x_auto_patch_ops; |
648 | 641 | ||
649 | return 0; | 642 | return 0; |
@@ -1240,7 +1233,7 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec) | |||
1240 | codec->inv_eapd = 1; | 1233 | codec->inv_eapd = 1; |
1241 | 1234 | ||
1242 | spec->gen.mixer_nid = 0x07; | 1235 | spec->gen.mixer_nid = 0x07; |
1243 | spec->beep_dev_nid = 0x19; | 1236 | spec->gen.beep_nid = 0x19; |
1244 | set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); | 1237 | set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); |
1245 | 1238 | ||
1246 | /* AD1986A has a hardware problem that it can't share a stream | 1239 | /* AD1986A has a hardware problem that it can't share a stream |
@@ -1256,7 +1249,7 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec) | |||
1256 | 1249 | ||
1257 | err = ad198x_parse_auto_config(codec); | 1250 | err = ad198x_parse_auto_config(codec); |
1258 | if (err < 0) { | 1251 | if (err < 0) { |
1259 | ad198x_free(codec); | 1252 | snd_hda_gen_free(codec); |
1260 | return err; | 1253 | return err; |
1261 | } | 1254 | } |
1262 | 1255 | ||
@@ -1673,7 +1666,7 @@ static int ad1983_parse_auto_config(struct hda_codec *codec) | |||
1673 | return err; | 1666 | return err; |
1674 | spec = codec->spec; | 1667 | spec = codec->spec; |
1675 | 1668 | ||
1676 | spec->beep_dev_nid = 0x10; | 1669 | spec->gen.beep_nid = 0x10; |
1677 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 1670 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
1678 | err = ad198x_parse_auto_config(codec); | 1671 | err = ad198x_parse_auto_config(codec); |
1679 | if (err < 0) | 1672 | if (err < 0) |
@@ -1684,7 +1677,7 @@ static int ad1983_parse_auto_config(struct hda_codec *codec) | |||
1684 | return 0; | 1677 | return 0; |
1685 | 1678 | ||
1686 | error: | 1679 | error: |
1687 | ad198x_free(codec); | 1680 | snd_hda_gen_free(codec); |
1688 | return err; | 1681 | return err; |
1689 | } | 1682 | } |
1690 | 1683 | ||
@@ -2187,7 +2180,7 @@ static int ad1981_parse_auto_config(struct hda_codec *codec) | |||
2187 | spec = codec->spec; | 2180 | spec = codec->spec; |
2188 | 2181 | ||
2189 | spec->gen.mixer_nid = 0x0e; | 2182 | spec->gen.mixer_nid = 0x0e; |
2190 | spec->beep_dev_nid = 0x10; | 2183 | spec->gen.beep_nid = 0x10; |
2191 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); | 2184 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); |
2192 | 2185 | ||
2193 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); | 2186 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); |
@@ -2205,7 +2198,7 @@ static int ad1981_parse_auto_config(struct hda_codec *codec) | |||
2205 | return 0; | 2198 | return 0; |
2206 | 2199 | ||
2207 | error: | 2200 | error: |
2208 | ad198x_free(codec); | 2201 | snd_hda_gen_free(codec); |
2209 | return err; | 2202 | return err; |
2210 | } | 2203 | } |
2211 | 2204 | ||
@@ -3236,7 +3229,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) | |||
3236 | 3229 | ||
3237 | spec->gen.mixer_nid = 0x20; | 3230 | spec->gen.mixer_nid = 0x20; |
3238 | spec->gen.mixer_merge_nid = 0x21; | 3231 | spec->gen.mixer_merge_nid = 0x21; |
3239 | spec->beep_dev_nid = 0x10; | 3232 | spec->gen.beep_nid = 0x10; |
3240 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 3233 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
3241 | err = ad198x_parse_auto_config(codec); | 3234 | err = ad198x_parse_auto_config(codec); |
3242 | if (err < 0) | 3235 | if (err < 0) |
@@ -3247,7 +3240,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) | |||
3247 | return 0; | 3240 | return 0; |
3248 | 3241 | ||
3249 | error: | 3242 | error: |
3250 | ad198x_free(codec); | 3243 | snd_hda_gen_free(codec); |
3251 | return err; | 3244 | return err; |
3252 | } | 3245 | } |
3253 | 3246 | ||
@@ -3653,7 +3646,7 @@ static int ad1884_parse_auto_config(struct hda_codec *codec) | |||
3653 | spec = codec->spec; | 3646 | spec = codec->spec; |
3654 | 3647 | ||
3655 | spec->gen.mixer_nid = 0x20; | 3648 | spec->gen.mixer_nid = 0x20; |
3656 | spec->beep_dev_nid = 0x10; | 3649 | spec->gen.beep_nid = 0x10; |
3657 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 3650 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
3658 | 3651 | ||
3659 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); | 3652 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); |
@@ -3671,7 +3664,7 @@ static int ad1884_parse_auto_config(struct hda_codec *codec) | |||
3671 | return 0; | 3664 | return 0; |
3672 | 3665 | ||
3673 | error: | 3666 | error: |
3674 | ad198x_free(codec); | 3667 | snd_hda_gen_free(codec); |
3675 | return err; | 3668 | return err; |
3676 | } | 3669 | } |
3677 | 3670 | ||
@@ -5155,7 +5148,7 @@ static int ad1882_parse_auto_config(struct hda_codec *codec) | |||
5155 | 5148 | ||
5156 | spec->gen.mixer_nid = 0x20; | 5149 | spec->gen.mixer_nid = 0x20; |
5157 | spec->gen.mixer_merge_nid = 0x21; | 5150 | spec->gen.mixer_merge_nid = 0x21; |
5158 | spec->beep_dev_nid = 0x10; | 5151 | spec->gen.beep_nid = 0x10; |
5159 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 5152 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
5160 | err = ad198x_parse_auto_config(codec); | 5153 | err = ad198x_parse_auto_config(codec); |
5161 | if (err < 0) | 5154 | if (err < 0) |
@@ -5166,7 +5159,7 @@ static int ad1882_parse_auto_config(struct hda_codec *codec) | |||
5166 | return 0; | 5159 | return 0; |
5167 | 5160 | ||
5168 | error: | 5161 | error: |
5169 | ad198x_free(codec); | 5162 | snd_hda_gen_free(codec); |
5170 | return err; | 5163 | return err; |
5171 | } | 5164 | } |
5172 | 5165 | ||
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 0792b5725f9c..90ff7a3f72df 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -131,6 +131,13 @@ enum { | |||
131 | /* Effects values size*/ | 131 | /* Effects values size*/ |
132 | #define EFFECT_VALS_MAX_COUNT 12 | 132 | #define EFFECT_VALS_MAX_COUNT 12 |
133 | 133 | ||
134 | /* Latency introduced by DSP blocks in milliseconds. */ | ||
135 | #define DSP_CAPTURE_INIT_LATENCY 0 | ||
136 | #define DSP_CRYSTAL_VOICE_LATENCY 124 | ||
137 | #define DSP_PLAYBACK_INIT_LATENCY 13 | ||
138 | #define DSP_PLAY_ENHANCEMENT_LATENCY 30 | ||
139 | #define DSP_SPEAKER_OUT_LATENCY 7 | ||
140 | |||
134 | struct ct_effect { | 141 | struct ct_effect { |
135 | char name[44]; | 142 | char name[44]; |
136 | hda_nid_t nid; | 143 | hda_nid_t nid; |
@@ -741,6 +748,9 @@ struct ca0132_spec { | |||
741 | long voicefx_val; | 748 | long voicefx_val; |
742 | long cur_mic_boost; | 749 | long cur_mic_boost; |
743 | 750 | ||
751 | struct hda_codec *codec; | ||
752 | struct delayed_work unsol_hp_work; | ||
753 | |||
744 | #ifdef ENABLE_TUNING_CONTROLS | 754 | #ifdef ENABLE_TUNING_CONTROLS |
745 | long cur_ctl_vals[TUNING_CTLS_COUNT]; | 755 | long cur_ctl_vals[TUNING_CTLS_COUNT]; |
746 | #endif | 756 | #endif |
@@ -2740,6 +2750,31 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2740 | return 0; | 2750 | return 0; |
2741 | } | 2751 | } |
2742 | 2752 | ||
2753 | static unsigned int ca0132_playback_pcm_delay(struct hda_pcm_stream *info, | ||
2754 | struct hda_codec *codec, | ||
2755 | struct snd_pcm_substream *substream) | ||
2756 | { | ||
2757 | struct ca0132_spec *spec = codec->spec; | ||
2758 | unsigned int latency = DSP_PLAYBACK_INIT_LATENCY; | ||
2759 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2760 | |||
2761 | if (spec->dsp_state != DSP_DOWNLOADED) | ||
2762 | return 0; | ||
2763 | |||
2764 | /* Add latency if playback enhancement and either effect is enabled. */ | ||
2765 | if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) { | ||
2766 | if ((spec->effects_switch[SURROUND - EFFECT_START_NID]) || | ||
2767 | (spec->effects_switch[DIALOG_PLUS - EFFECT_START_NID])) | ||
2768 | latency += DSP_PLAY_ENHANCEMENT_LATENCY; | ||
2769 | } | ||
2770 | |||
2771 | /* Applying Speaker EQ adds latency as well. */ | ||
2772 | if (spec->cur_out_type == SPEAKER_OUT) | ||
2773 | latency += DSP_SPEAKER_OUT_LATENCY; | ||
2774 | |||
2775 | return (latency * runtime->rate) / 1000; | ||
2776 | } | ||
2777 | |||
2743 | /* | 2778 | /* |
2744 | * Digital out | 2779 | * Digital out |
2745 | */ | 2780 | */ |
@@ -2808,6 +2843,23 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2808 | return 0; | 2843 | return 0; |
2809 | } | 2844 | } |
2810 | 2845 | ||
2846 | static unsigned int ca0132_capture_pcm_delay(struct hda_pcm_stream *info, | ||
2847 | struct hda_codec *codec, | ||
2848 | struct snd_pcm_substream *substream) | ||
2849 | { | ||
2850 | struct ca0132_spec *spec = codec->spec; | ||
2851 | unsigned int latency = DSP_CAPTURE_INIT_LATENCY; | ||
2852 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
2853 | |||
2854 | if (spec->dsp_state != DSP_DOWNLOADED) | ||
2855 | return 0; | ||
2856 | |||
2857 | if (spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID]) | ||
2858 | latency += DSP_CRYSTAL_VOICE_LATENCY; | ||
2859 | |||
2860 | return (latency * runtime->rate) / 1000; | ||
2861 | } | ||
2862 | |||
2811 | /* | 2863 | /* |
2812 | * Controls stuffs. | 2864 | * Controls stuffs. |
2813 | */ | 2865 | */ |
@@ -3227,6 +3279,14 @@ exit: | |||
3227 | return err < 0 ? err : 0; | 3279 | return err < 0 ? err : 0; |
3228 | } | 3280 | } |
3229 | 3281 | ||
3282 | static void ca0132_unsol_hp_delayed(struct work_struct *work) | ||
3283 | { | ||
3284 | struct ca0132_spec *spec = container_of( | ||
3285 | to_delayed_work(work), struct ca0132_spec, unsol_hp_work); | ||
3286 | ca0132_select_out(spec->codec); | ||
3287 | snd_hda_jack_report_sync(spec->codec); | ||
3288 | } | ||
3289 | |||
3230 | static void ca0132_set_dmic(struct hda_codec *codec, int enable); | 3290 | static void ca0132_set_dmic(struct hda_codec *codec, int enable); |
3231 | static int ca0132_mic_boost_set(struct hda_codec *codec, long val); | 3291 | static int ca0132_mic_boost_set(struct hda_codec *codec, long val); |
3232 | static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); | 3292 | static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); |
@@ -3991,7 +4051,8 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
3991 | .channels_max = 6, | 4051 | .channels_max = 6, |
3992 | .ops = { | 4052 | .ops = { |
3993 | .prepare = ca0132_playback_pcm_prepare, | 4053 | .prepare = ca0132_playback_pcm_prepare, |
3994 | .cleanup = ca0132_playback_pcm_cleanup | 4054 | .cleanup = ca0132_playback_pcm_cleanup, |
4055 | .get_delay = ca0132_playback_pcm_delay, | ||
3995 | }, | 4056 | }, |
3996 | }; | 4057 | }; |
3997 | 4058 | ||
@@ -4001,7 +4062,8 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
4001 | .channels_max = 2, | 4062 | .channels_max = 2, |
4002 | .ops = { | 4063 | .ops = { |
4003 | .prepare = ca0132_capture_pcm_prepare, | 4064 | .prepare = ca0132_capture_pcm_prepare, |
4004 | .cleanup = ca0132_capture_pcm_cleanup | 4065 | .cleanup = ca0132_capture_pcm_cleanup, |
4066 | .get_delay = ca0132_capture_pcm_delay, | ||
4005 | }, | 4067 | }, |
4006 | }; | 4068 | }; |
4007 | 4069 | ||
@@ -4399,8 +4461,7 @@ static void ca0132_process_dsp_response(struct hda_codec *codec) | |||
4399 | 4461 | ||
4400 | static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) | 4462 | static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) |
4401 | { | 4463 | { |
4402 | snd_printdd(KERN_INFO "ca0132_unsol_event: 0x%x\n", res); | 4464 | struct ca0132_spec *spec = codec->spec; |
4403 | |||
4404 | 4465 | ||
4405 | if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) { | 4466 | if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) { |
4406 | ca0132_process_dsp_response(codec); | 4467 | ca0132_process_dsp_response(codec); |
@@ -4412,8 +4473,13 @@ static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4412 | 4473 | ||
4413 | switch (res) { | 4474 | switch (res) { |
4414 | case UNSOL_TAG_HP: | 4475 | case UNSOL_TAG_HP: |
4415 | ca0132_select_out(codec); | 4476 | /* Delay enabling the HP amp, to let the mic-detection |
4416 | snd_hda_jack_report_sync(codec); | 4477 | * state machine run. |
4478 | */ | ||
4479 | cancel_delayed_work_sync(&spec->unsol_hp_work); | ||
4480 | queue_delayed_work(codec->bus->workq, | ||
4481 | &spec->unsol_hp_work, | ||
4482 | msecs_to_jiffies(500)); | ||
4417 | break; | 4483 | break; |
4418 | case UNSOL_TAG_AMIC1: | 4484 | case UNSOL_TAG_AMIC1: |
4419 | ca0132_select_mic(codec); | 4485 | ca0132_select_mic(codec); |
@@ -4588,6 +4654,7 @@ static void ca0132_free(struct hda_codec *codec) | |||
4588 | { | 4654 | { |
4589 | struct ca0132_spec *spec = codec->spec; | 4655 | struct ca0132_spec *spec = codec->spec; |
4590 | 4656 | ||
4657 | cancel_delayed_work_sync(&spec->unsol_hp_work); | ||
4591 | snd_hda_power_up(codec); | 4658 | snd_hda_power_up(codec); |
4592 | snd_hda_sequence_write(codec, spec->base_exit_verbs); | 4659 | snd_hda_sequence_write(codec, spec->base_exit_verbs); |
4593 | ca0132_exit_chip(codec); | 4660 | ca0132_exit_chip(codec); |
@@ -4653,6 +4720,7 @@ static int patch_ca0132(struct hda_codec *codec) | |||
4653 | if (!spec) | 4720 | if (!spec) |
4654 | return -ENOMEM; | 4721 | return -ENOMEM; |
4655 | codec->spec = spec; | 4722 | codec->spec = spec; |
4723 | spec->codec = codec; | ||
4656 | 4724 | ||
4657 | spec->num_mixers = 1; | 4725 | spec->num_mixers = 1; |
4658 | spec->mixers[0] = ca0132_mixer; | 4726 | spec->mixers[0] = ca0132_mixer; |
@@ -4663,6 +4731,8 @@ static int patch_ca0132(struct hda_codec *codec) | |||
4663 | spec->init_verbs[1] = ca0132_init_verbs1; | 4731 | spec->init_verbs[1] = ca0132_init_verbs1; |
4664 | spec->num_init_verbs = 2; | 4732 | spec->num_init_verbs = 2; |
4665 | 4733 | ||
4734 | INIT_DELAYED_WORK(&spec->unsol_hp_work, ca0132_unsol_hp_delayed); | ||
4735 | |||
4666 | ca0132_init_chip(codec); | 4736 | ca0132_init_chip(codec); |
4667 | 4737 | ||
4668 | ca0132_config(codec); | 4738 | ca0132_config(codec); |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 0d9c58f13560..bd8d46cca2b3 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -68,6 +68,7 @@ enum { | |||
68 | enum { | 68 | enum { |
69 | CS421X_CDB4210, | 69 | CS421X_CDB4210, |
70 | CS421X_SENSE_B, | 70 | CS421X_SENSE_B, |
71 | CS421X_STUMPY, | ||
71 | }; | 72 | }; |
72 | 73 | ||
73 | /* Vendor-specific processing widget */ | 74 | /* Vendor-specific processing widget */ |
@@ -538,6 +539,7 @@ static int patch_cs420x(struct hda_codec *codec) | |||
538 | /* CS4210 board names */ | 539 | /* CS4210 board names */ |
539 | static const struct hda_model_fixup cs421x_models[] = { | 540 | static const struct hda_model_fixup cs421x_models[] = { |
540 | { .id = CS421X_CDB4210, .name = "cdb4210" }, | 541 | { .id = CS421X_CDB4210, .name = "cdb4210" }, |
542 | { .id = CS421X_STUMPY, .name = "stumpy" }, | ||
541 | {} | 543 | {} |
542 | }; | 544 | }; |
543 | 545 | ||
@@ -559,6 +561,17 @@ static const struct hda_pintbl cdb4210_pincfgs[] = { | |||
559 | {} /* terminator */ | 561 | {} /* terminator */ |
560 | }; | 562 | }; |
561 | 563 | ||
564 | /* Stumpy ChromeBox */ | ||
565 | static const struct hda_pintbl stumpy_pincfgs[] = { | ||
566 | { 0x05, 0x022120f0 }, | ||
567 | { 0x06, 0x901700f0 }, | ||
568 | { 0x07, 0x02a120f0 }, | ||
569 | { 0x08, 0x77a70037 }, | ||
570 | { 0x09, 0x77a6003e }, | ||
571 | { 0x0a, 0x434510f0 }, | ||
572 | {} /* terminator */ | ||
573 | }; | ||
574 | |||
562 | /* Setup GPIO/SENSE for each board (if used) */ | 575 | /* Setup GPIO/SENSE for each board (if used) */ |
563 | static void cs421x_fixup_sense_b(struct hda_codec *codec, | 576 | static void cs421x_fixup_sense_b(struct hda_codec *codec, |
564 | const struct hda_fixup *fix, int action) | 577 | const struct hda_fixup *fix, int action) |
@@ -578,7 +591,11 @@ static const struct hda_fixup cs421x_fixups[] = { | |||
578 | [CS421X_SENSE_B] = { | 591 | [CS421X_SENSE_B] = { |
579 | .type = HDA_FIXUP_FUNC, | 592 | .type = HDA_FIXUP_FUNC, |
580 | .v.func = cs421x_fixup_sense_b, | 593 | .v.func = cs421x_fixup_sense_b, |
581 | } | 594 | }, |
595 | [CS421X_STUMPY] = { | ||
596 | .type = HDA_FIXUP_PINS, | ||
597 | .v.pins = stumpy_pincfgs, | ||
598 | }, | ||
582 | }; | 599 | }; |
583 | 600 | ||
584 | static const struct hda_verb cs421x_coef_init_verbs[] = { | 601 | static const struct hda_verb cs421x_coef_init_verbs[] = { |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2a89d1eefeb6..84b81c874a4a 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -139,8 +139,12 @@ struct conexant_spec { | |||
139 | 139 | ||
140 | 140 | ||
141 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 141 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
142 | #define set_beep_amp(spec, nid, idx, dir) \ | 142 | static inline void set_beep_amp(struct conexant_spec *spec, hda_nid_t nid, |
143 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) | 143 | int idx, int dir) |
144 | { | ||
145 | spec->gen.beep_nid = nid; | ||
146 | spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); | ||
147 | } | ||
144 | /* additional beep mixers; the actual parameters are overwritten at build */ | 148 | /* additional beep mixers; the actual parameters are overwritten at build */ |
145 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { | 149 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { |
146 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | 150 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), |
@@ -2942,7 +2946,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2942 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 2946 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
2943 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | 2947 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), |
2944 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), | 2948 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), |
2945 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | ||
2946 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), | 2949 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), |
2947 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), | 2950 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), |
2948 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | 2951 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), |
@@ -3191,17 +3194,11 @@ static int cx_auto_build_controls(struct hda_codec *codec) | |||
3191 | return 0; | 3194 | return 0; |
3192 | } | 3195 | } |
3193 | 3196 | ||
3194 | static void cx_auto_free(struct hda_codec *codec) | ||
3195 | { | ||
3196 | snd_hda_detach_beep_device(codec); | ||
3197 | snd_hda_gen_free(codec); | ||
3198 | } | ||
3199 | |||
3200 | static const struct hda_codec_ops cx_auto_patch_ops = { | 3197 | static const struct hda_codec_ops cx_auto_patch_ops = { |
3201 | .build_controls = cx_auto_build_controls, | 3198 | .build_controls = cx_auto_build_controls, |
3202 | .build_pcms = snd_hda_gen_build_pcms, | 3199 | .build_pcms = snd_hda_gen_build_pcms, |
3203 | .init = snd_hda_gen_init, | 3200 | .init = snd_hda_gen_init, |
3204 | .free = cx_auto_free, | 3201 | .free = snd_hda_gen_free, |
3205 | .unsol_event = snd_hda_jack_unsol_event, | 3202 | .unsol_event = snd_hda_jack_unsol_event, |
3206 | #ifdef CONFIG_PM | 3203 | #ifdef CONFIG_PM |
3207 | .check_power_status = snd_hda_gen_check_power_status, | 3204 | .check_power_status = snd_hda_gen_check_power_status, |
@@ -3310,6 +3307,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
3310 | SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), | 3307 | SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), |
3311 | SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), | 3308 | SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), |
3312 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), | 3309 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), |
3310 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), | ||
3313 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), | 3311 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), |
3314 | SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), | 3312 | SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), |
3315 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), | 3313 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), |
@@ -3356,7 +3354,6 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
3356 | switch (codec->vendor_id) { | 3354 | switch (codec->vendor_id) { |
3357 | case 0x14f15045: | 3355 | case 0x14f15045: |
3358 | codec->single_adc_amp = 1; | 3356 | codec->single_adc_amp = 1; |
3359 | codec->power_filter = NULL; /* Needs speaker amp to D3 to avoid click */ | ||
3360 | break; | 3357 | break; |
3361 | case 0x14f15047: | 3358 | case 0x14f15047: |
3362 | codec->pin_amp_workaround = 1; | 3359 | codec->pin_amp_workaround = 1; |
@@ -3396,8 +3393,6 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
3396 | goto error; | 3393 | goto error; |
3397 | 3394 | ||
3398 | codec->patch_ops = cx_auto_patch_ops; | 3395 | codec->patch_ops = cx_auto_patch_ops; |
3399 | if (spec->beep_amp) | ||
3400 | snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp)); | ||
3401 | 3396 | ||
3402 | /* Some laptops with Conexant chips show stalls in S3 resume, | 3397 | /* Some laptops with Conexant chips show stalls in S3 resume, |
3403 | * which falls into the single-cmd mode. | 3398 | * which falls into the single-cmd mode. |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index de8ac5c07fd0..32930e668854 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -44,16 +44,6 @@ static bool static_hdmi_pcm; | |||
44 | module_param(static_hdmi_pcm, bool, 0644); | 44 | module_param(static_hdmi_pcm, bool, 0644); |
45 | MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | 45 | MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); |
46 | 46 | ||
47 | /* | ||
48 | * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device | ||
49 | * could support N independent pipes, each of them can be connected to one or | ||
50 | * more ports (DVI, HDMI or DisplayPort). | ||
51 | * | ||
52 | * The HDA correspondence of pipes/ports are converter/pin nodes. | ||
53 | */ | ||
54 | #define MAX_HDMI_CVTS 8 | ||
55 | #define MAX_HDMI_PINS 8 | ||
56 | |||
57 | struct hdmi_spec_per_cvt { | 47 | struct hdmi_spec_per_cvt { |
58 | hda_nid_t cvt_nid; | 48 | hda_nid_t cvt_nid; |
59 | int assigned; | 49 | int assigned; |
@@ -80,16 +70,17 @@ struct hdmi_spec_per_pin { | |||
80 | bool non_pcm; | 70 | bool non_pcm; |
81 | bool chmap_set; /* channel-map override by ALSA API? */ | 71 | bool chmap_set; /* channel-map override by ALSA API? */ |
82 | unsigned char chmap[8]; /* ALSA API channel-map */ | 72 | unsigned char chmap[8]; /* ALSA API channel-map */ |
73 | char pcm_name[8]; /* filled in build_pcm callbacks */ | ||
83 | }; | 74 | }; |
84 | 75 | ||
85 | struct hdmi_spec { | 76 | struct hdmi_spec { |
86 | int num_cvts; | 77 | int num_cvts; |
87 | struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS]; | 78 | struct snd_array cvts; /* struct hdmi_spec_per_cvt */ |
88 | hda_nid_t cvt_nids[MAX_HDMI_CVTS]; | 79 | hda_nid_t cvt_nids[4]; /* only for haswell fix */ |
89 | 80 | ||
90 | int num_pins; | 81 | int num_pins; |
91 | struct hdmi_spec_per_pin pins[MAX_HDMI_PINS]; | 82 | struct snd_array pins; /* struct hdmi_spec_per_pin */ |
92 | struct hda_pcm pcm_rec[MAX_HDMI_PINS]; | 83 | struct snd_array pcm_rec; /* struct hda_pcm */ |
93 | unsigned int channels_max; /* max over all cvts */ | 84 | unsigned int channels_max; /* max over all cvts */ |
94 | 85 | ||
95 | struct hdmi_eld temp_eld; | 86 | struct hdmi_eld temp_eld; |
@@ -304,12 +295,19 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { | |||
304 | * HDMI routines | 295 | * HDMI routines |
305 | */ | 296 | */ |
306 | 297 | ||
298 | #define get_pin(spec, idx) \ | ||
299 | ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx)) | ||
300 | #define get_cvt(spec, idx) \ | ||
301 | ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx)) | ||
302 | #define get_pcm_rec(spec, idx) \ | ||
303 | ((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx)) | ||
304 | |||
307 | static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid) | 305 | static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid) |
308 | { | 306 | { |
309 | int pin_idx; | 307 | int pin_idx; |
310 | 308 | ||
311 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) | 309 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) |
312 | if (spec->pins[pin_idx].pin_nid == pin_nid) | 310 | if (get_pin(spec, pin_idx)->pin_nid == pin_nid) |
313 | return pin_idx; | 311 | return pin_idx; |
314 | 312 | ||
315 | snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid); | 313 | snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid); |
@@ -322,7 +320,7 @@ static int hinfo_to_pin_index(struct hdmi_spec *spec, | |||
322 | int pin_idx; | 320 | int pin_idx; |
323 | 321 | ||
324 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) | 322 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) |
325 | if (&spec->pcm_rec[pin_idx].stream[0] == hinfo) | 323 | if (get_pcm_rec(spec, pin_idx)->stream == hinfo) |
326 | return pin_idx; | 324 | return pin_idx; |
327 | 325 | ||
328 | snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo); | 326 | snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo); |
@@ -334,7 +332,7 @@ static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid) | |||
334 | int cvt_idx; | 332 | int cvt_idx; |
335 | 333 | ||
336 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) | 334 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) |
337 | if (spec->cvts[cvt_idx].cvt_nid == cvt_nid) | 335 | if (get_cvt(spec, cvt_idx)->cvt_nid == cvt_nid) |
338 | return cvt_idx; | 336 | return cvt_idx; |
339 | 337 | ||
340 | snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid); | 338 | snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid); |
@@ -352,7 +350,7 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, | |||
352 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | 350 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; |
353 | 351 | ||
354 | pin_idx = kcontrol->private_value; | 352 | pin_idx = kcontrol->private_value; |
355 | eld = &spec->pins[pin_idx].sink_eld; | 353 | eld = &get_pin(spec, pin_idx)->sink_eld; |
356 | 354 | ||
357 | mutex_lock(&eld->lock); | 355 | mutex_lock(&eld->lock); |
358 | uinfo->count = eld->eld_valid ? eld->eld_size : 0; | 356 | uinfo->count = eld->eld_valid ? eld->eld_size : 0; |
@@ -370,7 +368,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, | |||
370 | int pin_idx; | 368 | int pin_idx; |
371 | 369 | ||
372 | pin_idx = kcontrol->private_value; | 370 | pin_idx = kcontrol->private_value; |
373 | eld = &spec->pins[pin_idx].sink_eld; | 371 | eld = &get_pin(spec, pin_idx)->sink_eld; |
374 | 372 | ||
375 | mutex_lock(&eld->lock); | 373 | mutex_lock(&eld->lock); |
376 | if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { | 374 | if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { |
@@ -410,11 +408,11 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx, | |||
410 | kctl->private_value = pin_idx; | 408 | kctl->private_value = pin_idx; |
411 | kctl->id.device = device; | 409 | kctl->id.device = device; |
412 | 410 | ||
413 | err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl); | 411 | err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid, kctl); |
414 | if (err < 0) | 412 | if (err < 0) |
415 | return err; | 413 | return err; |
416 | 414 | ||
417 | spec->pins[pin_idx].eld_ctl = kctl; | 415 | get_pin(spec, pin_idx)->eld_ctl = kctl; |
418 | return 0; | 416 | return 0; |
419 | } | 417 | } |
420 | 418 | ||
@@ -875,14 +873,14 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
875 | struct snd_pcm_substream *substream) | 873 | struct snd_pcm_substream *substream) |
876 | { | 874 | { |
877 | struct hdmi_spec *spec = codec->spec; | 875 | struct hdmi_spec *spec = codec->spec; |
878 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 876 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
879 | hda_nid_t pin_nid = per_pin->pin_nid; | 877 | hda_nid_t pin_nid = per_pin->pin_nid; |
880 | int channels = substream->runtime->channels; | 878 | int channels = substream->runtime->channels; |
881 | struct hdmi_eld *eld; | 879 | struct hdmi_eld *eld; |
882 | int ca; | 880 | int ca; |
883 | union audio_infoframe ai; | 881 | union audio_infoframe ai; |
884 | 882 | ||
885 | eld = &spec->pins[pin_idx].sink_eld; | 883 | eld = &per_pin->sink_eld; |
886 | if (!eld->monitor_present) | 884 | if (!eld->monitor_present) |
887 | return; | 885 | return; |
888 | 886 | ||
@@ -977,7 +975,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
977 | if (pin_idx < 0) | 975 | if (pin_idx < 0) |
978 | return; | 976 | return; |
979 | 977 | ||
980 | hdmi_present_sense(&spec->pins[pin_idx], 1); | 978 | hdmi_present_sense(get_pin(spec, pin_idx), 1); |
981 | snd_hda_jack_report_sync(codec); | 979 | snd_hda_jack_report_sync(codec); |
982 | } | 980 | } |
983 | 981 | ||
@@ -1020,6 +1018,41 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1020 | hdmi_non_intrinsic_event(codec, res); | 1018 | hdmi_non_intrinsic_event(codec, res); |
1021 | } | 1019 | } |
1022 | 1020 | ||
1021 | static void haswell_verify_pin_D0(struct hda_codec *codec, hda_nid_t nid) | ||
1022 | { | ||
1023 | int pwr, lamp, ramp; | ||
1024 | |||
1025 | pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); | ||
1026 | pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT; | ||
1027 | if (pwr != AC_PWRST_D0) { | ||
1028 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, | ||
1029 | AC_PWRST_D0); | ||
1030 | msleep(40); | ||
1031 | pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); | ||
1032 | pwr = (pwr & AC_PWRST_ACTUAL) >> AC_PWRST_ACTUAL_SHIFT; | ||
1033 | snd_printd("Haswell HDMI audio: Power for pin 0x%x is now D%d\n", nid, pwr); | ||
1034 | } | ||
1035 | |||
1036 | lamp = snd_hda_codec_read(codec, nid, 0, | ||
1037 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
1038 | AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT); | ||
1039 | ramp = snd_hda_codec_read(codec, nid, 0, | ||
1040 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
1041 | AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT); | ||
1042 | if (lamp != ramp) { | ||
1043 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1044 | AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT | lamp); | ||
1045 | |||
1046 | lamp = snd_hda_codec_read(codec, nid, 0, | ||
1047 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
1048 | AC_AMP_GET_LEFT | AC_AMP_GET_OUTPUT); | ||
1049 | ramp = snd_hda_codec_read(codec, nid, 0, | ||
1050 | AC_VERB_GET_AMP_GAIN_MUTE, | ||
1051 | AC_AMP_GET_RIGHT | AC_AMP_GET_OUTPUT); | ||
1052 | snd_printd("Haswell HDMI audio: Mute after set on pin 0x%x: [0x%x 0x%x]\n", nid, lamp, ramp); | ||
1053 | } | ||
1054 | } | ||
1055 | |||
1023 | /* | 1056 | /* |
1024 | * Callbacks | 1057 | * Callbacks |
1025 | */ | 1058 | */ |
@@ -1034,6 +1067,9 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, | |||
1034 | int pinctl; | 1067 | int pinctl; |
1035 | int new_pinctl = 0; | 1068 | int new_pinctl = 0; |
1036 | 1069 | ||
1070 | if (codec->vendor_id == 0x80862807) | ||
1071 | haswell_verify_pin_D0(codec, pin_nid); | ||
1072 | |||
1037 | if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) { | 1073 | if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) { |
1038 | pinctl = snd_hda_codec_read(codec, pin_nid, 0, | 1074 | pinctl = snd_hda_codec_read(codec, pin_nid, 0, |
1039 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 1075 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
@@ -1083,12 +1119,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
1083 | pin_idx = hinfo_to_pin_index(spec, hinfo); | 1119 | pin_idx = hinfo_to_pin_index(spec, hinfo); |
1084 | if (snd_BUG_ON(pin_idx < 0)) | 1120 | if (snd_BUG_ON(pin_idx < 0)) |
1085 | return -EINVAL; | 1121 | return -EINVAL; |
1086 | per_pin = &spec->pins[pin_idx]; | 1122 | per_pin = get_pin(spec, pin_idx); |
1087 | eld = &per_pin->sink_eld; | 1123 | eld = &per_pin->sink_eld; |
1088 | 1124 | ||
1089 | /* Dynamically assign converter to stream */ | 1125 | /* Dynamically assign converter to stream */ |
1090 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { | 1126 | for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { |
1091 | per_cvt = &spec->cvts[cvt_idx]; | 1127 | per_cvt = get_cvt(spec, cvt_idx); |
1092 | 1128 | ||
1093 | /* Must not already be assigned */ | 1129 | /* Must not already be assigned */ |
1094 | if (per_cvt->assigned) | 1130 | if (per_cvt->assigned) |
@@ -1151,7 +1187,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
1151 | static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) | 1187 | static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) |
1152 | { | 1188 | { |
1153 | struct hdmi_spec *spec = codec->spec; | 1189 | struct hdmi_spec *spec = codec->spec; |
1154 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1190 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1155 | hda_nid_t pin_nid = per_pin->pin_nid; | 1191 | hda_nid_t pin_nid = per_pin->pin_nid; |
1156 | 1192 | ||
1157 | if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { | 1193 | if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { |
@@ -1275,14 +1311,13 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
1275 | if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) | 1311 | if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) |
1276 | return 0; | 1312 | return 0; |
1277 | 1313 | ||
1278 | if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS)) | ||
1279 | return -E2BIG; | ||
1280 | |||
1281 | if (codec->vendor_id == 0x80862807) | 1314 | if (codec->vendor_id == 0x80862807) |
1282 | intel_haswell_fixup_connect_list(codec, pin_nid); | 1315 | intel_haswell_fixup_connect_list(codec, pin_nid); |
1283 | 1316 | ||
1284 | pin_idx = spec->num_pins; | 1317 | pin_idx = spec->num_pins; |
1285 | per_pin = &spec->pins[pin_idx]; | 1318 | per_pin = snd_array_new(&spec->pins); |
1319 | if (!per_pin) | ||
1320 | return -ENOMEM; | ||
1286 | 1321 | ||
1287 | per_pin->pin_nid = pin_nid; | 1322 | per_pin->pin_nid = pin_nid; |
1288 | per_pin->non_pcm = false; | 1323 | per_pin->non_pcm = false; |
@@ -1299,19 +1334,16 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
1299 | static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) | 1334 | static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) |
1300 | { | 1335 | { |
1301 | struct hdmi_spec *spec = codec->spec; | 1336 | struct hdmi_spec *spec = codec->spec; |
1302 | int cvt_idx; | ||
1303 | struct hdmi_spec_per_cvt *per_cvt; | 1337 | struct hdmi_spec_per_cvt *per_cvt; |
1304 | unsigned int chans; | 1338 | unsigned int chans; |
1305 | int err; | 1339 | int err; |
1306 | 1340 | ||
1307 | if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) | ||
1308 | return -E2BIG; | ||
1309 | |||
1310 | chans = get_wcaps(codec, cvt_nid); | 1341 | chans = get_wcaps(codec, cvt_nid); |
1311 | chans = get_wcaps_channels(chans); | 1342 | chans = get_wcaps_channels(chans); |
1312 | 1343 | ||
1313 | cvt_idx = spec->num_cvts; | 1344 | per_cvt = snd_array_new(&spec->cvts); |
1314 | per_cvt = &spec->cvts[cvt_idx]; | 1345 | if (!per_cvt) |
1346 | return -ENOMEM; | ||
1315 | 1347 | ||
1316 | per_cvt->cvt_nid = cvt_nid; | 1348 | per_cvt->cvt_nid = cvt_nid; |
1317 | per_cvt->channels_min = 2; | 1349 | per_cvt->channels_min = 2; |
@@ -1328,7 +1360,9 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) | |||
1328 | if (err < 0) | 1360 | if (err < 0) |
1329 | return err; | 1361 | return err; |
1330 | 1362 | ||
1331 | spec->cvt_nids[spec->num_cvts++] = cvt_nid; | 1363 | if (spec->num_cvts < ARRAY_SIZE(spec->cvt_nids)) |
1364 | spec->cvt_nids[spec->num_cvts] = cvt_nid; | ||
1365 | spec->num_cvts++; | ||
1332 | 1366 | ||
1333 | return 0; | 1367 | return 0; |
1334 | } | 1368 | } |
@@ -1384,13 +1418,6 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
1384 | 1418 | ||
1385 | /* | 1419 | /* |
1386 | */ | 1420 | */ |
1387 | static char *get_hdmi_pcm_name(int idx) | ||
1388 | { | ||
1389 | static char names[MAX_HDMI_PINS][8]; | ||
1390 | sprintf(&names[idx][0], "HDMI %d", idx); | ||
1391 | return &names[idx][0]; | ||
1392 | } | ||
1393 | |||
1394 | static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) | 1421 | static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) |
1395 | { | 1422 | { |
1396 | struct hda_spdif_out *spdif; | 1423 | struct hda_spdif_out *spdif; |
@@ -1417,7 +1444,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1417 | hda_nid_t cvt_nid = hinfo->nid; | 1444 | hda_nid_t cvt_nid = hinfo->nid; |
1418 | struct hdmi_spec *spec = codec->spec; | 1445 | struct hdmi_spec *spec = codec->spec; |
1419 | int pin_idx = hinfo_to_pin_index(spec, hinfo); | 1446 | int pin_idx = hinfo_to_pin_index(spec, hinfo); |
1420 | hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; | 1447 | hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid; |
1421 | bool non_pcm; | 1448 | bool non_pcm; |
1422 | 1449 | ||
1423 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 1450 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); |
@@ -1450,7 +1477,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
1450 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); | 1477 | cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); |
1451 | if (snd_BUG_ON(cvt_idx < 0)) | 1478 | if (snd_BUG_ON(cvt_idx < 0)) |
1452 | return -EINVAL; | 1479 | return -EINVAL; |
1453 | per_cvt = &spec->cvts[cvt_idx]; | 1480 | per_cvt = get_cvt(spec, cvt_idx); |
1454 | 1481 | ||
1455 | snd_BUG_ON(!per_cvt->assigned); | 1482 | snd_BUG_ON(!per_cvt->assigned); |
1456 | per_cvt->assigned = 0; | 1483 | per_cvt->assigned = 0; |
@@ -1459,7 +1486,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
1459 | pin_idx = hinfo_to_pin_index(spec, hinfo); | 1486 | pin_idx = hinfo_to_pin_index(spec, hinfo); |
1460 | if (snd_BUG_ON(pin_idx < 0)) | 1487 | if (snd_BUG_ON(pin_idx < 0)) |
1461 | return -EINVAL; | 1488 | return -EINVAL; |
1462 | per_pin = &spec->pins[pin_idx]; | 1489 | per_pin = get_pin(spec, pin_idx); |
1463 | 1490 | ||
1464 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1491 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
1465 | per_pin->chmap_set = false; | 1492 | per_pin->chmap_set = false; |
@@ -1553,7 +1580,7 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol, | |||
1553 | struct hda_codec *codec = info->private_data; | 1580 | struct hda_codec *codec = info->private_data; |
1554 | struct hdmi_spec *spec = codec->spec; | 1581 | struct hdmi_spec *spec = codec->spec; |
1555 | int pin_idx = kcontrol->private_value; | 1582 | int pin_idx = kcontrol->private_value; |
1556 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1583 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1557 | int i; | 1584 | int i; |
1558 | 1585 | ||
1559 | for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++) | 1586 | for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++) |
@@ -1568,7 +1595,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, | |||
1568 | struct hda_codec *codec = info->private_data; | 1595 | struct hda_codec *codec = info->private_data; |
1569 | struct hdmi_spec *spec = codec->spec; | 1596 | struct hdmi_spec *spec = codec->spec; |
1570 | int pin_idx = kcontrol->private_value; | 1597 | int pin_idx = kcontrol->private_value; |
1571 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1598 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1572 | unsigned int ctl_idx; | 1599 | unsigned int ctl_idx; |
1573 | struct snd_pcm_substream *substream; | 1600 | struct snd_pcm_substream *substream; |
1574 | unsigned char chmap[8]; | 1601 | unsigned char chmap[8]; |
@@ -1613,9 +1640,14 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
1613 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1640 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1614 | struct hda_pcm *info; | 1641 | struct hda_pcm *info; |
1615 | struct hda_pcm_stream *pstr; | 1642 | struct hda_pcm_stream *pstr; |
1616 | 1643 | struct hdmi_spec_per_pin *per_pin; | |
1617 | info = &spec->pcm_rec[pin_idx]; | 1644 | |
1618 | info->name = get_hdmi_pcm_name(pin_idx); | 1645 | per_pin = get_pin(spec, pin_idx); |
1646 | sprintf(per_pin->pcm_name, "HDMI %d", pin_idx); | ||
1647 | info = snd_array_new(&spec->pcm_rec); | ||
1648 | if (!info) | ||
1649 | return -ENOMEM; | ||
1650 | info->name = per_pin->pcm_name; | ||
1619 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1651 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1620 | info->own_chmap = true; | 1652 | info->own_chmap = true; |
1621 | 1653 | ||
@@ -1626,7 +1658,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
1626 | } | 1658 | } |
1627 | 1659 | ||
1628 | codec->num_pcms = spec->num_pins; | 1660 | codec->num_pcms = spec->num_pins; |
1629 | codec->pcm_info = spec->pcm_rec; | 1661 | codec->pcm_info = spec->pcm_rec.list; |
1630 | 1662 | ||
1631 | return 0; | 1663 | return 0; |
1632 | } | 1664 | } |
@@ -1635,8 +1667,8 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | |||
1635 | { | 1667 | { |
1636 | char hdmi_str[32] = "HDMI/DP"; | 1668 | char hdmi_str[32] = "HDMI/DP"; |
1637 | struct hdmi_spec *spec = codec->spec; | 1669 | struct hdmi_spec *spec = codec->spec; |
1638 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1670 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1639 | int pcmdev = spec->pcm_rec[pin_idx].device; | 1671 | int pcmdev = get_pcm_rec(spec, pin_idx)->device; |
1640 | 1672 | ||
1641 | if (pcmdev > 0) | 1673 | if (pcmdev > 0) |
1642 | sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); | 1674 | sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); |
@@ -1654,7 +1686,7 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1654 | int pin_idx; | 1686 | int pin_idx; |
1655 | 1687 | ||
1656 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1688 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1657 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1689 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1658 | 1690 | ||
1659 | err = generic_hdmi_build_jack(codec, pin_idx); | 1691 | err = generic_hdmi_build_jack(codec, pin_idx); |
1660 | if (err < 0) | 1692 | if (err < 0) |
@@ -1669,9 +1701,8 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1669 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1701 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
1670 | 1702 | ||
1671 | /* add control for ELD Bytes */ | 1703 | /* add control for ELD Bytes */ |
1672 | err = hdmi_create_eld_ctl(codec, | 1704 | err = hdmi_create_eld_ctl(codec, pin_idx, |
1673 | pin_idx, | 1705 | get_pcm_rec(spec, pin_idx)->device); |
1674 | spec->pcm_rec[pin_idx].device); | ||
1675 | 1706 | ||
1676 | if (err < 0) | 1707 | if (err < 0) |
1677 | return err; | 1708 | return err; |
@@ -1709,7 +1740,7 @@ static int generic_hdmi_init_per_pins(struct hda_codec *codec) | |||
1709 | int pin_idx; | 1740 | int pin_idx; |
1710 | 1741 | ||
1711 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1742 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1712 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1743 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1713 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1744 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1714 | 1745 | ||
1715 | per_pin->codec = codec; | 1746 | per_pin->codec = codec; |
@@ -1726,7 +1757,7 @@ static int generic_hdmi_init(struct hda_codec *codec) | |||
1726 | int pin_idx; | 1757 | int pin_idx; |
1727 | 1758 | ||
1728 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1759 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1729 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1760 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1730 | hda_nid_t pin_nid = per_pin->pin_nid; | 1761 | hda_nid_t pin_nid = per_pin->pin_nid; |
1731 | 1762 | ||
1732 | hdmi_init_pin(codec, pin_nid); | 1763 | hdmi_init_pin(codec, pin_nid); |
@@ -1735,13 +1766,27 @@ static int generic_hdmi_init(struct hda_codec *codec) | |||
1735 | return 0; | 1766 | return 0; |
1736 | } | 1767 | } |
1737 | 1768 | ||
1769 | static void hdmi_array_init(struct hdmi_spec *spec, int nums) | ||
1770 | { | ||
1771 | snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums); | ||
1772 | snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums); | ||
1773 | snd_array_init(&spec->pcm_rec, sizeof(struct hda_pcm), nums); | ||
1774 | } | ||
1775 | |||
1776 | static void hdmi_array_free(struct hdmi_spec *spec) | ||
1777 | { | ||
1778 | snd_array_free(&spec->pins); | ||
1779 | snd_array_free(&spec->cvts); | ||
1780 | snd_array_free(&spec->pcm_rec); | ||
1781 | } | ||
1782 | |||
1738 | static void generic_hdmi_free(struct hda_codec *codec) | 1783 | static void generic_hdmi_free(struct hda_codec *codec) |
1739 | { | 1784 | { |
1740 | struct hdmi_spec *spec = codec->spec; | 1785 | struct hdmi_spec *spec = codec->spec; |
1741 | int pin_idx; | 1786 | int pin_idx; |
1742 | 1787 | ||
1743 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1788 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1744 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1789 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1745 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1790 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1746 | 1791 | ||
1747 | cancel_delayed_work(&per_pin->work); | 1792 | cancel_delayed_work(&per_pin->work); |
@@ -1749,6 +1794,7 @@ static void generic_hdmi_free(struct hda_codec *codec) | |||
1749 | } | 1794 | } |
1750 | 1795 | ||
1751 | flush_workqueue(codec->bus->workq); | 1796 | flush_workqueue(codec->bus->workq); |
1797 | hdmi_array_free(spec); | ||
1752 | kfree(spec); | 1798 | kfree(spec); |
1753 | } | 1799 | } |
1754 | 1800 | ||
@@ -1775,6 +1821,7 @@ static void intel_haswell_fixup_connect_list(struct hda_codec *codec, | |||
1775 | 1821 | ||
1776 | /* override pins connection list */ | 1822 | /* override pins connection list */ |
1777 | snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid); | 1823 | snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid); |
1824 | nconns = max(spec->num_cvts, 4); | ||
1778 | snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids); | 1825 | snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids); |
1779 | } | 1826 | } |
1780 | 1827 | ||
@@ -1855,6 +1902,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1855 | return -ENOMEM; | 1902 | return -ENOMEM; |
1856 | 1903 | ||
1857 | codec->spec = spec; | 1904 | codec->spec = spec; |
1905 | hdmi_array_init(spec, 4); | ||
1858 | 1906 | ||
1859 | snd_hda_pick_fixup(codec, hdmi_models, hdmi_fixup_tbl, hdmi_fixups); | 1907 | snd_hda_pick_fixup(codec, hdmi_models, hdmi_fixup_tbl, hdmi_fixups); |
1860 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1908 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
@@ -1882,24 +1930,30 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1882 | static int simple_playback_build_pcms(struct hda_codec *codec) | 1930 | static int simple_playback_build_pcms(struct hda_codec *codec) |
1883 | { | 1931 | { |
1884 | struct hdmi_spec *spec = codec->spec; | 1932 | struct hdmi_spec *spec = codec->spec; |
1885 | struct hda_pcm *info = spec->pcm_rec; | 1933 | struct hda_pcm *info; |
1886 | unsigned int chans; | 1934 | unsigned int chans; |
1887 | struct hda_pcm_stream *pstr; | 1935 | struct hda_pcm_stream *pstr; |
1936 | struct hdmi_spec_per_cvt *per_cvt; | ||
1888 | 1937 | ||
1889 | codec->num_pcms = 1; | 1938 | per_cvt = get_cvt(spec, 0); |
1890 | codec->pcm_info = info; | 1939 | chans = get_wcaps(codec, per_cvt->cvt_nid); |
1891 | |||
1892 | chans = get_wcaps(codec, spec->cvts[0].cvt_nid); | ||
1893 | chans = get_wcaps_channels(chans); | 1940 | chans = get_wcaps_channels(chans); |
1894 | 1941 | ||
1895 | info->name = get_hdmi_pcm_name(0); | 1942 | info = snd_array_new(&spec->pcm_rec); |
1943 | if (!info) | ||
1944 | return -ENOMEM; | ||
1945 | info->name = get_pin(spec, 0)->pcm_name; | ||
1946 | sprintf(info->name, "HDMI 0"); | ||
1896 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1947 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1897 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1948 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1898 | *pstr = spec->pcm_playback; | 1949 | *pstr = spec->pcm_playback; |
1899 | pstr->nid = spec->cvts[0].cvt_nid; | 1950 | pstr->nid = per_cvt->cvt_nid; |
1900 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 1951 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
1901 | pstr->channels_max = chans; | 1952 | pstr->channels_max = chans; |
1902 | 1953 | ||
1954 | codec->num_pcms = 1; | ||
1955 | codec->pcm_info = info; | ||
1956 | |||
1903 | return 0; | 1957 | return 0; |
1904 | } | 1958 | } |
1905 | 1959 | ||
@@ -1919,11 +1973,12 @@ static void simple_hdmi_unsol_event(struct hda_codec *codec, | |||
1919 | static int simple_playback_build_controls(struct hda_codec *codec) | 1973 | static int simple_playback_build_controls(struct hda_codec *codec) |
1920 | { | 1974 | { |
1921 | struct hdmi_spec *spec = codec->spec; | 1975 | struct hdmi_spec *spec = codec->spec; |
1976 | struct hdmi_spec_per_cvt *per_cvt; | ||
1922 | int err; | 1977 | int err; |
1923 | 1978 | ||
1924 | err = snd_hda_create_spdif_out_ctls(codec, | 1979 | per_cvt = get_cvt(spec, 0); |
1925 | spec->cvts[0].cvt_nid, | 1980 | err = snd_hda_create_spdif_out_ctls(codec, per_cvt->cvt_nid, |
1926 | spec->cvts[0].cvt_nid); | 1981 | per_cvt->cvt_nid); |
1927 | if (err < 0) | 1982 | if (err < 0) |
1928 | return err; | 1983 | return err; |
1929 | return simple_hdmi_build_jack(codec, 0); | 1984 | return simple_hdmi_build_jack(codec, 0); |
@@ -1932,7 +1987,8 @@ static int simple_playback_build_controls(struct hda_codec *codec) | |||
1932 | static int simple_playback_init(struct hda_codec *codec) | 1987 | static int simple_playback_init(struct hda_codec *codec) |
1933 | { | 1988 | { |
1934 | struct hdmi_spec *spec = codec->spec; | 1989 | struct hdmi_spec *spec = codec->spec; |
1935 | hda_nid_t pin = spec->pins[0].pin_nid; | 1990 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, 0); |
1991 | hda_nid_t pin = per_pin->pin_nid; | ||
1936 | 1992 | ||
1937 | snd_hda_codec_write(codec, pin, 0, | 1993 | snd_hda_codec_write(codec, pin, 0, |
1938 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 1994 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
@@ -1948,6 +2004,7 @@ static void simple_playback_free(struct hda_codec *codec) | |||
1948 | { | 2004 | { |
1949 | struct hdmi_spec *spec = codec->spec; | 2005 | struct hdmi_spec *spec = codec->spec; |
1950 | 2006 | ||
2007 | hdmi_array_free(spec); | ||
1951 | kfree(spec); | 2008 | kfree(spec); |
1952 | } | 2009 | } |
1953 | 2010 | ||
@@ -2111,20 +2168,29 @@ static int patch_simple_hdmi(struct hda_codec *codec, | |||
2111 | hda_nid_t cvt_nid, hda_nid_t pin_nid) | 2168 | hda_nid_t cvt_nid, hda_nid_t pin_nid) |
2112 | { | 2169 | { |
2113 | struct hdmi_spec *spec; | 2170 | struct hdmi_spec *spec; |
2171 | struct hdmi_spec_per_cvt *per_cvt; | ||
2172 | struct hdmi_spec_per_pin *per_pin; | ||
2114 | 2173 | ||
2115 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2174 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
2116 | if (!spec) | 2175 | if (!spec) |
2117 | return -ENOMEM; | 2176 | return -ENOMEM; |
2118 | 2177 | ||
2119 | codec->spec = spec; | 2178 | codec->spec = spec; |
2179 | hdmi_array_init(spec, 1); | ||
2120 | 2180 | ||
2121 | spec->multiout.num_dacs = 0; /* no analog */ | 2181 | spec->multiout.num_dacs = 0; /* no analog */ |
2122 | spec->multiout.max_channels = 2; | 2182 | spec->multiout.max_channels = 2; |
2123 | spec->multiout.dig_out_nid = cvt_nid; | 2183 | spec->multiout.dig_out_nid = cvt_nid; |
2124 | spec->num_cvts = 1; | 2184 | spec->num_cvts = 1; |
2125 | spec->num_pins = 1; | 2185 | spec->num_pins = 1; |
2126 | spec->cvts[0].cvt_nid = cvt_nid; | 2186 | per_pin = snd_array_new(&spec->pins); |
2127 | spec->pins[0].pin_nid = pin_nid; | 2187 | per_cvt = snd_array_new(&spec->cvts); |
2188 | if (!per_pin || !per_cvt) { | ||
2189 | simple_playback_free(codec); | ||
2190 | return -ENOMEM; | ||
2191 | } | ||
2192 | per_cvt->cvt_nid = cvt_nid; | ||
2193 | per_pin->pin_nid = pin_nid; | ||
2128 | spec->pcm_playback = simple_pcm_playback; | 2194 | spec->pcm_playback = simple_pcm_playback; |
2129 | 2195 | ||
2130 | codec->patch_ops = simple_hdmi_patch_ops; | 2196 | codec->patch_ops = simple_hdmi_patch_ops; |
@@ -2201,9 +2267,11 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2201 | int i; | 2267 | int i; |
2202 | struct hdmi_spec *spec = codec->spec; | 2268 | struct hdmi_spec *spec = codec->spec; |
2203 | struct hda_spdif_out *spdif; | 2269 | struct hda_spdif_out *spdif; |
2270 | struct hdmi_spec_per_cvt *per_cvt; | ||
2204 | 2271 | ||
2205 | mutex_lock(&codec->spdif_mutex); | 2272 | mutex_lock(&codec->spdif_mutex); |
2206 | spdif = snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid); | 2273 | per_cvt = get_cvt(spec, 0); |
2274 | spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid); | ||
2207 | 2275 | ||
2208 | chs = substream->runtime->channels; | 2276 | chs = substream->runtime->channels; |
2209 | 2277 | ||
@@ -2325,13 +2393,17 @@ static int nvhdmi_7x_8ch_build_pcms(struct hda_codec *codec) | |||
2325 | { | 2393 | { |
2326 | struct hdmi_spec *spec = codec->spec; | 2394 | struct hdmi_spec *spec = codec->spec; |
2327 | int err = simple_playback_build_pcms(codec); | 2395 | int err = simple_playback_build_pcms(codec); |
2328 | spec->pcm_rec[0].own_chmap = true; | 2396 | if (!err) { |
2397 | struct hda_pcm *info = get_pcm_rec(spec, 0); | ||
2398 | info->own_chmap = true; | ||
2399 | } | ||
2329 | return err; | 2400 | return err; |
2330 | } | 2401 | } |
2331 | 2402 | ||
2332 | static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec) | 2403 | static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec) |
2333 | { | 2404 | { |
2334 | struct hdmi_spec *spec = codec->spec; | 2405 | struct hdmi_spec *spec = codec->spec; |
2406 | struct hda_pcm *info; | ||
2335 | struct snd_pcm_chmap *chmap; | 2407 | struct snd_pcm_chmap *chmap; |
2336 | int err; | 2408 | int err; |
2337 | 2409 | ||
@@ -2340,7 +2412,8 @@ static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec) | |||
2340 | return err; | 2412 | return err; |
2341 | 2413 | ||
2342 | /* add channel maps */ | 2414 | /* add channel maps */ |
2343 | err = snd_pcm_add_chmap_ctls(spec->pcm_rec[0].pcm, | 2415 | info = get_pcm_rec(spec, 0); |
2416 | err = snd_pcm_add_chmap_ctls(info->pcm, | ||
2344 | SNDRV_PCM_STREAM_PLAYBACK, | 2417 | SNDRV_PCM_STREAM_PLAYBACK, |
2345 | snd_pcm_alt_chmaps, 8, 0, &chmap); | 2418 | snd_pcm_alt_chmaps, 8, 0, &chmap); |
2346 | if (err < 0) | 2419 | if (err < 0) |
@@ -2395,6 +2468,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2395 | struct snd_pcm_substream *substream) | 2468 | struct snd_pcm_substream *substream) |
2396 | { | 2469 | { |
2397 | struct hdmi_spec *spec = codec->spec; | 2470 | struct hdmi_spec *spec = codec->spec; |
2471 | struct hdmi_spec_per_cvt *per_cvt = get_cvt(spec, 0); | ||
2398 | int chans = substream->runtime->channels; | 2472 | int chans = substream->runtime->channels; |
2399 | int i, err; | 2473 | int i, err; |
2400 | 2474 | ||
@@ -2402,11 +2476,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2402 | substream); | 2476 | substream); |
2403 | if (err < 0) | 2477 | if (err < 0) |
2404 | return err; | 2478 | return err; |
2405 | snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, | 2479 | snd_hda_codec_write(codec, per_cvt->cvt_nid, 0, |
2406 | AC_VERB_SET_CVT_CHAN_COUNT, chans - 1); | 2480 | AC_VERB_SET_CVT_CHAN_COUNT, chans - 1); |
2407 | /* FIXME: XXX */ | 2481 | /* FIXME: XXX */ |
2408 | for (i = 0; i < chans; i++) { | 2482 | for (i = 0; i < chans; i++) { |
2409 | snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, | 2483 | snd_hda_codec_write(codec, per_cvt->cvt_nid, 0, |
2410 | AC_VERB_SET_HDMI_CHAN_SLOT, | 2484 | AC_VERB_SET_HDMI_CHAN_SLOT, |
2411 | (i << 4) | i); | 2485 | (i << 4) | i); |
2412 | } | 2486 | } |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f15c36bde540..6bf47f7326ad 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include "hda_codec.h" | 34 | #include "hda_codec.h" |
35 | #include "hda_local.h" | 35 | #include "hda_local.h" |
36 | #include "hda_auto_parser.h" | 36 | #include "hda_auto_parser.h" |
37 | #include "hda_beep.h" | ||
38 | #include "hda_jack.h" | 37 | #include "hda_jack.h" |
39 | #include "hda_generic.h" | 38 | #include "hda_generic.h" |
40 | 39 | ||
@@ -53,6 +52,20 @@ enum { | |||
53 | ALC_INIT_GPIO3, | 52 | ALC_INIT_GPIO3, |
54 | }; | 53 | }; |
55 | 54 | ||
55 | enum { | ||
56 | ALC_HEADSET_MODE_UNKNOWN, | ||
57 | ALC_HEADSET_MODE_UNPLUGGED, | ||
58 | ALC_HEADSET_MODE_HEADSET, | ||
59 | ALC_HEADSET_MODE_MIC, | ||
60 | ALC_HEADSET_MODE_HEADPHONE, | ||
61 | }; | ||
62 | |||
63 | enum { | ||
64 | ALC_HEADSET_TYPE_UNKNOWN, | ||
65 | ALC_HEADSET_TYPE_CTIA, | ||
66 | ALC_HEADSET_TYPE_OMTP, | ||
67 | }; | ||
68 | |||
56 | struct alc_customize_define { | 69 | struct alc_customize_define { |
57 | unsigned int sku_cfg; | 70 | unsigned int sku_cfg; |
58 | unsigned char port_connectivity; | 71 | unsigned char port_connectivity; |
@@ -86,6 +99,13 @@ struct alc_spec { | |||
86 | int mute_led_polarity; | 99 | int mute_led_polarity; |
87 | hda_nid_t mute_led_nid; | 100 | hda_nid_t mute_led_nid; |
88 | 101 | ||
102 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | ||
103 | |||
104 | hda_nid_t headset_mic_pin; | ||
105 | hda_nid_t headphone_mic_pin; | ||
106 | int current_headset_mode; | ||
107 | int current_headset_type; | ||
108 | |||
89 | /* hooks */ | 109 | /* hooks */ |
90 | void (*init_hook)(struct hda_codec *codec); | 110 | void (*init_hook)(struct hda_codec *codec); |
91 | #ifdef CONFIG_PM | 111 | #ifdef CONFIG_PM |
@@ -805,17 +825,7 @@ static inline void alc_shutup(struct hda_codec *codec) | |||
805 | snd_hda_shutup_pins(codec); | 825 | snd_hda_shutup_pins(codec); |
806 | } | 826 | } |
807 | 827 | ||
808 | static void alc_free(struct hda_codec *codec) | 828 | #define alc_free snd_hda_gen_free |
809 | { | ||
810 | struct alc_spec *spec = codec->spec; | ||
811 | |||
812 | if (!spec) | ||
813 | return; | ||
814 | |||
815 | snd_hda_gen_spec_free(&spec->gen); | ||
816 | snd_hda_detach_beep_device(codec); | ||
817 | kfree(spec); | ||
818 | } | ||
819 | 829 | ||
820 | #ifdef CONFIG_PM | 830 | #ifdef CONFIG_PM |
821 | static void alc_power_eapd(struct hda_codec *codec) | 831 | static void alc_power_eapd(struct hda_codec *codec) |
@@ -1401,6 +1411,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
1401 | 1411 | ||
1402 | spec = codec->spec; | 1412 | spec = codec->spec; |
1403 | spec->gen.need_dac_fix = 1; | 1413 | spec->gen.need_dac_fix = 1; |
1414 | spec->gen.beep_nid = 0x01; | ||
1404 | 1415 | ||
1405 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, | 1416 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, |
1406 | alc880_fixups); | 1417 | alc880_fixups); |
@@ -1411,12 +1422,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
1411 | if (err < 0) | 1422 | if (err < 0) |
1412 | goto error; | 1423 | goto error; |
1413 | 1424 | ||
1414 | if (!spec->gen.no_analog) { | 1425 | if (!spec->gen.no_analog) |
1415 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
1416 | if (err < 0) | ||
1417 | goto error; | ||
1418 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 1426 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
1419 | } | ||
1420 | 1427 | ||
1421 | codec->patch_ops = alc_patch_ops; | 1428 | codec->patch_ops = alc_patch_ops; |
1422 | codec->patch_ops.unsol_event = alc880_unsol_event; | 1429 | codec->patch_ops.unsol_event = alc880_unsol_event; |
@@ -1455,6 +1462,7 @@ enum { | |||
1455 | ALC260_FIXUP_HP_B1900, | 1462 | ALC260_FIXUP_HP_B1900, |
1456 | ALC260_FIXUP_KN1, | 1463 | ALC260_FIXUP_KN1, |
1457 | ALC260_FIXUP_FSC_S7020, | 1464 | ALC260_FIXUP_FSC_S7020, |
1465 | ALC260_FIXUP_FSC_S7020_JWSE, | ||
1458 | }; | 1466 | }; |
1459 | 1467 | ||
1460 | static void alc260_gpio1_automute(struct hda_codec *codec) | 1468 | static void alc260_gpio1_automute(struct hda_codec *codec) |
@@ -1516,14 +1524,17 @@ static void alc260_fixup_fsc_s7020(struct hda_codec *codec, | |||
1516 | const struct hda_fixup *fix, int action) | 1524 | const struct hda_fixup *fix, int action) |
1517 | { | 1525 | { |
1518 | struct alc_spec *spec = codec->spec; | 1526 | struct alc_spec *spec = codec->spec; |
1519 | 1527 | if (action == HDA_FIXUP_ACT_PROBE) | |
1520 | switch (action) { | ||
1521 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
1522 | spec->gen.add_out_jack_modes = 1; | ||
1523 | break; | ||
1524 | case HDA_FIXUP_ACT_PROBE: | ||
1525 | spec->init_amp = ALC_INIT_NONE; | 1528 | spec->init_amp = ALC_INIT_NONE; |
1526 | break; | 1529 | } |
1530 | |||
1531 | static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, | ||
1532 | const struct hda_fixup *fix, int action) | ||
1533 | { | ||
1534 | struct alc_spec *spec = codec->spec; | ||
1535 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
1536 | spec->gen.add_jack_modes = 1; | ||
1537 | spec->gen.hp_mic = 1; | ||
1527 | } | 1538 | } |
1528 | } | 1539 | } |
1529 | 1540 | ||
@@ -1586,6 +1597,12 @@ static const struct hda_fixup alc260_fixups[] = { | |||
1586 | .type = HDA_FIXUP_FUNC, | 1597 | .type = HDA_FIXUP_FUNC, |
1587 | .v.func = alc260_fixup_fsc_s7020, | 1598 | .v.func = alc260_fixup_fsc_s7020, |
1588 | }, | 1599 | }, |
1600 | [ALC260_FIXUP_FSC_S7020_JWSE] = { | ||
1601 | .type = HDA_FIXUP_FUNC, | ||
1602 | .v.func = alc260_fixup_fsc_s7020_jwse, | ||
1603 | .chained = true, | ||
1604 | .chain_id = ALC260_FIXUP_FSC_S7020, | ||
1605 | }, | ||
1589 | }; | 1606 | }; |
1590 | 1607 | ||
1591 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 1608 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
@@ -1602,6 +1619,14 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { | |||
1602 | {} | 1619 | {} |
1603 | }; | 1620 | }; |
1604 | 1621 | ||
1622 | static const struct hda_model_fixup alc260_fixup_models[] = { | ||
1623 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, | ||
1624 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, | ||
1625 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, | ||
1626 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, | ||
1627 | {} | ||
1628 | }; | ||
1629 | |||
1605 | /* | 1630 | /* |
1606 | */ | 1631 | */ |
1607 | static int patch_alc260(struct hda_codec *codec) | 1632 | static int patch_alc260(struct hda_codec *codec) |
@@ -1619,8 +1644,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
1619 | * it's almost harmless. | 1644 | * it's almost harmless. |
1620 | */ | 1645 | */ |
1621 | spec->gen.prefer_hp_amp = 1; | 1646 | spec->gen.prefer_hp_amp = 1; |
1647 | spec->gen.beep_nid = 0x01; | ||
1622 | 1648 | ||
1623 | snd_hda_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); | 1649 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, |
1650 | alc260_fixups); | ||
1624 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1651 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1625 | 1652 | ||
1626 | /* automatic parse from the BIOS config */ | 1653 | /* automatic parse from the BIOS config */ |
@@ -1628,12 +1655,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
1628 | if (err < 0) | 1655 | if (err < 0) |
1629 | goto error; | 1656 | goto error; |
1630 | 1657 | ||
1631 | if (!spec->gen.no_analog) { | 1658 | if (!spec->gen.no_analog) |
1632 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
1633 | if (err < 0) | ||
1634 | goto error; | ||
1635 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 1659 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
1636 | } | ||
1637 | 1660 | ||
1638 | codec->patch_ops = alc_patch_ops; | 1661 | codec->patch_ops = alc_patch_ops; |
1639 | spec->shutup = alc_eapd_shutup; | 1662 | spec->shutup = alc_eapd_shutup; |
@@ -2132,17 +2155,16 @@ static int patch_alc882(struct hda_codec *codec) | |||
2132 | 2155 | ||
2133 | alc_auto_parse_customize_define(codec); | 2156 | alc_auto_parse_customize_define(codec); |
2134 | 2157 | ||
2158 | if (has_cdefine_beep(codec)) | ||
2159 | spec->gen.beep_nid = 0x01; | ||
2160 | |||
2135 | /* automatic parse from the BIOS config */ | 2161 | /* automatic parse from the BIOS config */ |
2136 | err = alc882_parse_auto_config(codec); | 2162 | err = alc882_parse_auto_config(codec); |
2137 | if (err < 0) | 2163 | if (err < 0) |
2138 | goto error; | 2164 | goto error; |
2139 | 2165 | ||
2140 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { | 2166 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2141 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
2142 | if (err < 0) | ||
2143 | goto error; | ||
2144 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2167 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2145 | } | ||
2146 | 2168 | ||
2147 | codec->patch_ops = alc_patch_ops; | 2169 | codec->patch_ops = alc_patch_ops; |
2148 | 2170 | ||
@@ -2295,17 +2317,16 @@ static int patch_alc262(struct hda_codec *codec) | |||
2295 | 2317 | ||
2296 | alc_auto_parse_customize_define(codec); | 2318 | alc_auto_parse_customize_define(codec); |
2297 | 2319 | ||
2320 | if (has_cdefine_beep(codec)) | ||
2321 | spec->gen.beep_nid = 0x01; | ||
2322 | |||
2298 | /* automatic parse from the BIOS config */ | 2323 | /* automatic parse from the BIOS config */ |
2299 | err = alc262_parse_auto_config(codec); | 2324 | err = alc262_parse_auto_config(codec); |
2300 | if (err < 0) | 2325 | if (err < 0) |
2301 | goto error; | 2326 | goto error; |
2302 | 2327 | ||
2303 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { | 2328 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2304 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
2305 | if (err < 0) | ||
2306 | goto error; | ||
2307 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2329 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2308 | } | ||
2309 | 2330 | ||
2310 | codec->patch_ops = alc_patch_ops; | 2331 | codec->patch_ops = alc_patch_ops; |
2311 | spec->shutup = alc_eapd_shutup; | 2332 | spec->shutup = alc_eapd_shutup; |
@@ -2386,16 +2407,7 @@ static const struct snd_pci_quirk alc268_fixup_tbl[] = { | |||
2386 | static int alc268_parse_auto_config(struct hda_codec *codec) | 2407 | static int alc268_parse_auto_config(struct hda_codec *codec) |
2387 | { | 2408 | { |
2388 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2409 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2389 | struct alc_spec *spec = codec->spec; | 2410 | return alc_parse_auto_config(codec, NULL, alc268_ssids); |
2390 | int err = alc_parse_auto_config(codec, NULL, alc268_ssids); | ||
2391 | if (err > 0) { | ||
2392 | if (!spec->gen.no_analog && | ||
2393 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { | ||
2394 | add_mixer(spec, alc268_beep_mixer); | ||
2395 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); | ||
2396 | } | ||
2397 | } | ||
2398 | return err; | ||
2399 | } | 2411 | } |
2400 | 2412 | ||
2401 | /* | 2413 | /* |
@@ -2403,7 +2415,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
2403 | static int patch_alc268(struct hda_codec *codec) | 2415 | static int patch_alc268(struct hda_codec *codec) |
2404 | { | 2416 | { |
2405 | struct alc_spec *spec; | 2417 | struct alc_spec *spec; |
2406 | int i, has_beep, err; | 2418 | int err; |
2407 | 2419 | ||
2408 | /* ALC268 has no aa-loopback mixer */ | 2420 | /* ALC268 has no aa-loopback mixer */ |
2409 | err = alc_alloc_spec(codec, 0); | 2421 | err = alc_alloc_spec(codec, 0); |
@@ -2411,6 +2423,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
2411 | return err; | 2423 | return err; |
2412 | 2424 | ||
2413 | spec = codec->spec; | 2425 | spec = codec->spec; |
2426 | spec->gen.beep_nid = 0x01; | ||
2414 | 2427 | ||
2415 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); | 2428 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); |
2416 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2429 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
@@ -2420,18 +2433,10 @@ static int patch_alc268(struct hda_codec *codec) | |||
2420 | if (err < 0) | 2433 | if (err < 0) |
2421 | goto error; | 2434 | goto error; |
2422 | 2435 | ||
2423 | has_beep = 0; | 2436 | if (err > 0 && !spec->gen.no_analog && |
2424 | for (i = 0; i < spec->num_mixers; i++) { | 2437 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { |
2425 | if (spec->mixers[i] == alc268_beep_mixer) { | 2438 | add_mixer(spec, alc268_beep_mixer); |
2426 | has_beep = 1; | 2439 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); |
2427 | break; | ||
2428 | } | ||
2429 | } | ||
2430 | |||
2431 | if (has_beep) { | ||
2432 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
2433 | if (err < 0) | ||
2434 | goto error; | ||
2435 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 2440 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
2436 | /* override the amp caps for beep generator */ | 2441 | /* override the amp caps for beep generator */ |
2437 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 2442 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, |
@@ -2515,6 +2520,7 @@ enum { | |||
2515 | ALC269_TYPE_ALC280, | 2520 | ALC269_TYPE_ALC280, |
2516 | ALC269_TYPE_ALC282, | 2521 | ALC269_TYPE_ALC282, |
2517 | ALC269_TYPE_ALC284, | 2522 | ALC269_TYPE_ALC284, |
2523 | ALC269_TYPE_ALC286, | ||
2518 | }; | 2524 | }; |
2519 | 2525 | ||
2520 | /* | 2526 | /* |
@@ -2538,6 +2544,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
2538 | case ALC269_TYPE_ALC269VB: | 2544 | case ALC269_TYPE_ALC269VB: |
2539 | case ALC269_TYPE_ALC269VD: | 2545 | case ALC269_TYPE_ALC269VD: |
2540 | case ALC269_TYPE_ALC282: | 2546 | case ALC269_TYPE_ALC282: |
2547 | case ALC269_TYPE_ALC286: | ||
2541 | ssids = alc269_ssids; | 2548 | ssids = alc269_ssids; |
2542 | break; | 2549 | break; |
2543 | default: | 2550 | default: |
@@ -2631,7 +2638,8 @@ static void alc271_fixup_dmic(struct hda_codec *codec, | |||
2631 | }; | 2638 | }; |
2632 | unsigned int cfg; | 2639 | unsigned int cfg; |
2633 | 2640 | ||
2634 | if (strcmp(codec->chip_name, "ALC271X")) | 2641 | if (strcmp(codec->chip_name, "ALC271X") && |
2642 | strcmp(codec->chip_name, "ALC269VB")) | ||
2635 | return; | 2643 | return; |
2636 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); | 2644 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); |
2637 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) | 2645 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) |
@@ -2693,6 +2701,34 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec, | |||
2693 | spec->gen.automute_hook = alc269_quanta_automute; | 2701 | spec->gen.automute_hook = alc269_quanta_automute; |
2694 | } | 2702 | } |
2695 | 2703 | ||
2704 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | ||
2705 | struct hda_jack_tbl *jack) | ||
2706 | { | ||
2707 | struct alc_spec *spec = codec->spec; | ||
2708 | int vref; | ||
2709 | msleep(200); | ||
2710 | snd_hda_gen_hp_automute(codec, jack); | ||
2711 | |||
2712 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | ||
2713 | msleep(100); | ||
2714 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2715 | vref); | ||
2716 | msleep(500); | ||
2717 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
2718 | vref); | ||
2719 | } | ||
2720 | |||
2721 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, | ||
2722 | const struct hda_fixup *fix, int action) | ||
2723 | { | ||
2724 | struct alc_spec *spec = codec->spec; | ||
2725 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2726 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | ||
2727 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; | ||
2728 | } | ||
2729 | } | ||
2730 | |||
2731 | |||
2696 | /* update mute-LED according to the speaker mute state via mic VREF pin */ | 2732 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
2697 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | 2733 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
2698 | { | 2734 | { |
@@ -2757,6 +2793,356 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | |||
2757 | } | 2793 | } |
2758 | } | 2794 | } |
2759 | 2795 | ||
2796 | /* turn on/off mute LED per vmaster hook */ | ||
2797 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | ||
2798 | { | ||
2799 | struct hda_codec *codec = private_data; | ||
2800 | struct alc_spec *spec = codec->spec; | ||
2801 | unsigned int oldval = spec->gpio_led; | ||
2802 | |||
2803 | if (enabled) | ||
2804 | spec->gpio_led &= ~0x08; | ||
2805 | else | ||
2806 | spec->gpio_led |= 0x08; | ||
2807 | if (spec->gpio_led != oldval) | ||
2808 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
2809 | spec->gpio_led); | ||
2810 | } | ||
2811 | |||
2812 | /* turn on/off mic-mute LED per capture hook */ | ||
2813 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | ||
2814 | struct snd_ctl_elem_value *ucontrol) | ||
2815 | { | ||
2816 | struct alc_spec *spec = codec->spec; | ||
2817 | unsigned int oldval = spec->gpio_led; | ||
2818 | |||
2819 | if (!ucontrol) | ||
2820 | return; | ||
2821 | |||
2822 | if (ucontrol->value.integer.value[0] || | ||
2823 | ucontrol->value.integer.value[1]) | ||
2824 | spec->gpio_led &= ~0x10; | ||
2825 | else | ||
2826 | spec->gpio_led |= 0x10; | ||
2827 | if (spec->gpio_led != oldval) | ||
2828 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
2829 | spec->gpio_led); | ||
2830 | } | ||
2831 | |||
2832 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | ||
2833 | const struct hda_fixup *fix, int action) | ||
2834 | { | ||
2835 | struct alc_spec *spec = codec->spec; | ||
2836 | static const struct hda_verb gpio_init[] = { | ||
2837 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, | ||
2838 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, | ||
2839 | {} | ||
2840 | }; | ||
2841 | |||
2842 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
2843 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | ||
2844 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | ||
2845 | spec->gpio_led = 0; | ||
2846 | snd_hda_add_verbs(codec, gpio_init); | ||
2847 | } | ||
2848 | } | ||
2849 | |||
2850 | static void alc_headset_mode_unplugged(struct hda_codec *codec) | ||
2851 | { | ||
2852 | int val; | ||
2853 | |||
2854 | switch (codec->vendor_id) { | ||
2855 | case 0x10ec0283: | ||
2856 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | ||
2857 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
2858 | val = alc_read_coef_idx(codec, 0x35); | ||
2859 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); | ||
2860 | alc_write_coef_idx(codec, 0x06, 0x2104); | ||
2861 | alc_write_coef_idx(codec, 0x1a, 0x0001); | ||
2862 | alc_write_coef_idx(codec, 0x26, 0x0004); | ||
2863 | alc_write_coef_idx(codec, 0x32, 0x42a3); | ||
2864 | break; | ||
2865 | case 0x10ec0292: | ||
2866 | alc_write_coef_idx(codec, 0x76, 0x000e); | ||
2867 | alc_write_coef_idx(codec, 0x6c, 0x2400); | ||
2868 | alc_write_coef_idx(codec, 0x18, 0x7308); | ||
2869 | alc_write_coef_idx(codec, 0x6b, 0xc429); | ||
2870 | break; | ||
2871 | case 0x10ec0668: | ||
2872 | alc_write_coef_idx(codec, 0x15, 0x0d40); | ||
2873 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2874 | break; | ||
2875 | } | ||
2876 | snd_printdd("Headset jack set to unplugged mode.\n"); | ||
2877 | } | ||
2878 | |||
2879 | |||
2880 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | ||
2881 | hda_nid_t mic_pin) | ||
2882 | { | ||
2883 | int val; | ||
2884 | |||
2885 | switch (codec->vendor_id) { | ||
2886 | case 0x10ec0283: | ||
2887 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
2888 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2889 | val = alc_read_coef_idx(codec, 0x35); | ||
2890 | alc_write_coef_idx(codec, 0x35, val | 1<<14); | ||
2891 | alc_write_coef_idx(codec, 0x06, 0x2100); | ||
2892 | alc_write_coef_idx(codec, 0x1a, 0x0021); | ||
2893 | alc_write_coef_idx(codec, 0x26, 0x008c); | ||
2894 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
2895 | break; | ||
2896 | case 0x10ec0292: | ||
2897 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2898 | alc_write_coef_idx(codec, 0x19, 0xa208); | ||
2899 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | ||
2900 | break; | ||
2901 | case 0x10ec0668: | ||
2902 | alc_write_coef_idx(codec, 0x11, 0x0001); | ||
2903 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
2904 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2905 | alc_write_coef_idx(codec, 0xb5, 0x1040); | ||
2906 | val = alc_read_coef_idx(codec, 0xc3); | ||
2907 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); | ||
2908 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
2909 | break; | ||
2910 | } | ||
2911 | snd_printdd("Headset jack set to mic-in mode.\n"); | ||
2912 | } | ||
2913 | |||
2914 | static void alc_headset_mode_default(struct hda_codec *codec) | ||
2915 | { | ||
2916 | switch (codec->vendor_id) { | ||
2917 | case 0x10ec0283: | ||
2918 | alc_write_coef_idx(codec, 0x06, 0x2100); | ||
2919 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2920 | break; | ||
2921 | case 0x10ec0292: | ||
2922 | alc_write_coef_idx(codec, 0x76, 0x000e); | ||
2923 | alc_write_coef_idx(codec, 0x6c, 0x2400); | ||
2924 | alc_write_coef_idx(codec, 0x6b, 0xc429); | ||
2925 | alc_write_coef_idx(codec, 0x18, 0x7308); | ||
2926 | break; | ||
2927 | case 0x10ec0668: | ||
2928 | alc_write_coef_idx(codec, 0x11, 0x0041); | ||
2929 | alc_write_coef_idx(codec, 0x15, 0x0d40); | ||
2930 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
2931 | break; | ||
2932 | } | ||
2933 | snd_printdd("Headset jack set to headphone (default) mode.\n"); | ||
2934 | } | ||
2935 | |||
2936 | /* Iphone type */ | ||
2937 | static void alc_headset_mode_ctia(struct hda_codec *codec) | ||
2938 | { | ||
2939 | switch (codec->vendor_id) { | ||
2940 | case 0x10ec0283: | ||
2941 | alc_write_coef_idx(codec, 0x45, 0xd429); | ||
2942 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
2943 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2944 | break; | ||
2945 | case 0x10ec0292: | ||
2946 | alc_write_coef_idx(codec, 0x6b, 0xd429); | ||
2947 | alc_write_coef_idx(codec, 0x76, 0x0008); | ||
2948 | alc_write_coef_idx(codec, 0x18, 0x7388); | ||
2949 | break; | ||
2950 | case 0x10ec0668: | ||
2951 | alc_write_coef_idx(codec, 0x15, 0x0d60); | ||
2952 | alc_write_coef_idx(codec, 0xc3, 0x0000); | ||
2953 | break; | ||
2954 | } | ||
2955 | snd_printdd("Headset jack set to iPhone-style headset mode.\n"); | ||
2956 | } | ||
2957 | |||
2958 | /* Nokia type */ | ||
2959 | static void alc_headset_mode_omtp(struct hda_codec *codec) | ||
2960 | { | ||
2961 | switch (codec->vendor_id) { | ||
2962 | case 0x10ec0283: | ||
2963 | alc_write_coef_idx(codec, 0x45, 0xe429); | ||
2964 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | ||
2965 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | ||
2966 | break; | ||
2967 | case 0x10ec0292: | ||
2968 | alc_write_coef_idx(codec, 0x6b, 0xe429); | ||
2969 | alc_write_coef_idx(codec, 0x76, 0x0008); | ||
2970 | alc_write_coef_idx(codec, 0x18, 0x7388); | ||
2971 | break; | ||
2972 | case 0x10ec0668: | ||
2973 | alc_write_coef_idx(codec, 0x15, 0x0d50); | ||
2974 | alc_write_coef_idx(codec, 0xc3, 0x0000); | ||
2975 | break; | ||
2976 | } | ||
2977 | snd_printdd("Headset jack set to Nokia-style headset mode.\n"); | ||
2978 | } | ||
2979 | |||
2980 | static void alc_determine_headset_type(struct hda_codec *codec) | ||
2981 | { | ||
2982 | int val; | ||
2983 | bool is_ctia = false; | ||
2984 | struct alc_spec *spec = codec->spec; | ||
2985 | |||
2986 | switch (codec->vendor_id) { | ||
2987 | case 0x10ec0283: | ||
2988 | alc_write_coef_idx(codec, 0x45, 0xd029); | ||
2989 | msleep(300); | ||
2990 | val = alc_read_coef_idx(codec, 0x46); | ||
2991 | is_ctia = (val & 0x0070) == 0x0070; | ||
2992 | break; | ||
2993 | case 0x10ec0292: | ||
2994 | alc_write_coef_idx(codec, 0x6b, 0xd429); | ||
2995 | msleep(300); | ||
2996 | val = alc_read_coef_idx(codec, 0x6c); | ||
2997 | is_ctia = (val & 0x001c) == 0x001c; | ||
2998 | break; | ||
2999 | case 0x10ec0668: | ||
3000 | alc_write_coef_idx(codec, 0x11, 0x0001); | ||
3001 | alc_write_coef_idx(codec, 0xb7, 0x802b); | ||
3002 | alc_write_coef_idx(codec, 0x15, 0x0d60); | ||
3003 | alc_write_coef_idx(codec, 0xc3, 0x0c00); | ||
3004 | msleep(300); | ||
3005 | val = alc_read_coef_idx(codec, 0xbe); | ||
3006 | is_ctia = (val & 0x1c02) == 0x1c02; | ||
3007 | break; | ||
3008 | } | ||
3009 | |||
3010 | snd_printdd("Headset jack detected iPhone-style headset: %s\n", | ||
3011 | is_ctia ? "yes" : "no"); | ||
3012 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; | ||
3013 | } | ||
3014 | |||
3015 | static void alc_update_headset_mode(struct hda_codec *codec) | ||
3016 | { | ||
3017 | struct alc_spec *spec = codec->spec; | ||
3018 | |||
3019 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | ||
3020 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3021 | |||
3022 | int new_headset_mode; | ||
3023 | |||
3024 | if (!snd_hda_jack_detect(codec, hp_pin)) | ||
3025 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; | ||
3026 | else if (mux_pin == spec->headset_mic_pin) | ||
3027 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; | ||
3028 | else if (mux_pin == spec->headphone_mic_pin) | ||
3029 | new_headset_mode = ALC_HEADSET_MODE_MIC; | ||
3030 | else | ||
3031 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; | ||
3032 | |||
3033 | if (new_headset_mode == spec->current_headset_mode) | ||
3034 | return; | ||
3035 | |||
3036 | switch (new_headset_mode) { | ||
3037 | case ALC_HEADSET_MODE_UNPLUGGED: | ||
3038 | alc_headset_mode_unplugged(codec); | ||
3039 | spec->gen.hp_jack_present = false; | ||
3040 | break; | ||
3041 | case ALC_HEADSET_MODE_HEADSET: | ||
3042 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) | ||
3043 | alc_determine_headset_type(codec); | ||
3044 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) | ||
3045 | alc_headset_mode_ctia(codec); | ||
3046 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) | ||
3047 | alc_headset_mode_omtp(codec); | ||
3048 | spec->gen.hp_jack_present = true; | ||
3049 | break; | ||
3050 | case ALC_HEADSET_MODE_MIC: | ||
3051 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); | ||
3052 | spec->gen.hp_jack_present = false; | ||
3053 | break; | ||
3054 | case ALC_HEADSET_MODE_HEADPHONE: | ||
3055 | alc_headset_mode_default(codec); | ||
3056 | spec->gen.hp_jack_present = true; | ||
3057 | break; | ||
3058 | } | ||
3059 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { | ||
3060 | snd_hda_set_pin_ctl_cache(codec, hp_pin, | ||
3061 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
3062 | if (spec->headphone_mic_pin) | ||
3063 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, | ||
3064 | PIN_VREFHIZ); | ||
3065 | } | ||
3066 | spec->current_headset_mode = new_headset_mode; | ||
3067 | |||
3068 | snd_hda_gen_update_outputs(codec); | ||
3069 | } | ||
3070 | |||
3071 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | ||
3072 | struct snd_ctl_elem_value *ucontrol) | ||
3073 | { | ||
3074 | alc_update_headset_mode(codec); | ||
3075 | } | ||
3076 | |||
3077 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | ||
3078 | { | ||
3079 | struct alc_spec *spec = codec->spec; | ||
3080 | spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN; | ||
3081 | snd_hda_gen_hp_automute(codec, jack); | ||
3082 | } | ||
3083 | |||
3084 | static void alc_probe_headset_mode(struct hda_codec *codec) | ||
3085 | { | ||
3086 | int i; | ||
3087 | struct alc_spec *spec = codec->spec; | ||
3088 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
3089 | |||
3090 | /* Find mic pins */ | ||
3091 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3092 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) | ||
3093 | spec->headset_mic_pin = cfg->inputs[i].pin; | ||
3094 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) | ||
3095 | spec->headphone_mic_pin = cfg->inputs[i].pin; | ||
3096 | } | ||
3097 | |||
3098 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; | ||
3099 | spec->gen.automute_hook = alc_update_headset_mode; | ||
3100 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; | ||
3101 | } | ||
3102 | |||
3103 | static void alc_fixup_headset_mode(struct hda_codec *codec, | ||
3104 | const struct hda_fixup *fix, int action) | ||
3105 | { | ||
3106 | struct alc_spec *spec = codec->spec; | ||
3107 | |||
3108 | switch (action) { | ||
3109 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
3110 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; | ||
3111 | break; | ||
3112 | case HDA_FIXUP_ACT_PROBE: | ||
3113 | alc_probe_headset_mode(codec); | ||
3114 | break; | ||
3115 | case HDA_FIXUP_ACT_INIT: | ||
3116 | spec->current_headset_mode = 0; | ||
3117 | alc_update_headset_mode(codec); | ||
3118 | break; | ||
3119 | } | ||
3120 | } | ||
3121 | |||
3122 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | ||
3123 | const struct hda_fixup *fix, int action) | ||
3124 | { | ||
3125 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3126 | struct alc_spec *spec = codec->spec; | ||
3127 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | ||
3128 | } | ||
3129 | else | ||
3130 | alc_fixup_headset_mode(codec, fix, action); | ||
3131 | } | ||
3132 | |||
3133 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | ||
3134 | const struct hda_fixup *fix, int action) | ||
3135 | { | ||
3136 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3137 | int val; | ||
3138 | alc_write_coef_idx(codec, 0xc4, 0x8000); | ||
3139 | val = alc_read_coef_idx(codec, 0xc2); | ||
3140 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); | ||
3141 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); | ||
3142 | } | ||
3143 | alc_fixup_headset_mode(codec, fix, action); | ||
3144 | } | ||
3145 | |||
2760 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 3146 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
2761 | const struct hda_fixup *fix, | 3147 | const struct hda_fixup *fix, |
2762 | int action) | 3148 | int action) |
@@ -2772,6 +3158,38 @@ static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | |||
2772 | } | 3158 | } |
2773 | } | 3159 | } |
2774 | 3160 | ||
3161 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, | ||
3162 | const struct hda_fixup *fix, | ||
3163 | int action) | ||
3164 | { | ||
3165 | struct alc_spec *spec = codec->spec; | ||
3166 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | ||
3167 | int i; | ||
3168 | |||
3169 | /* The mic boosts on level 2 and 3 are too noisy | ||
3170 | on the internal mic input. | ||
3171 | Therefore limit the boost to 0 or 1. */ | ||
3172 | |||
3173 | if (action != HDA_FIXUP_ACT_PROBE) | ||
3174 | return; | ||
3175 | |||
3176 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3177 | hda_nid_t nid = cfg->inputs[i].pin; | ||
3178 | unsigned int defcfg; | ||
3179 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
3180 | continue; | ||
3181 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3182 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | ||
3183 | continue; | ||
3184 | |||
3185 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, | ||
3186 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | | ||
3187 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
3188 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
3189 | (0 << AC_AMPCAP_MUTE_SHIFT)); | ||
3190 | } | ||
3191 | } | ||
3192 | |||
2775 | enum { | 3193 | enum { |
2776 | ALC269_FIXUP_SONY_VAIO, | 3194 | ALC269_FIXUP_SONY_VAIO, |
2777 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 3195 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
@@ -2792,11 +3210,21 @@ enum { | |||
2792 | ALC269_FIXUP_HP_MUTE_LED, | 3210 | ALC269_FIXUP_HP_MUTE_LED, |
2793 | ALC269_FIXUP_HP_MUTE_LED_MIC1, | 3211 | ALC269_FIXUP_HP_MUTE_LED_MIC1, |
2794 | ALC269_FIXUP_HP_MUTE_LED_MIC2, | 3212 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
3213 | ALC269_FIXUP_HP_GPIO_LED, | ||
2795 | ALC269_FIXUP_INV_DMIC, | 3214 | ALC269_FIXUP_INV_DMIC, |
2796 | ALC269_FIXUP_LENOVO_DOCK, | 3215 | ALC269_FIXUP_LENOVO_DOCK, |
2797 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 3216 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
3217 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
3218 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | ||
3219 | ALC269_FIXUP_HEADSET_MODE, | ||
3220 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | ||
3221 | ALC269_FIXUP_ASUS_X101_FUNC, | ||
3222 | ALC269_FIXUP_ASUS_X101_VERB, | ||
3223 | ALC269_FIXUP_ASUS_X101, | ||
2798 | ALC271_FIXUP_AMIC_MIC2, | 3224 | ALC271_FIXUP_AMIC_MIC2, |
2799 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 3225 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
3226 | ALC269_FIXUP_ACER_AC700, | ||
3227 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, | ||
2800 | }; | 3228 | }; |
2801 | 3229 | ||
2802 | static const struct hda_fixup alc269_fixups[] = { | 3230 | static const struct hda_fixup alc269_fixups[] = { |
@@ -2931,6 +3359,10 @@ static const struct hda_fixup alc269_fixups[] = { | |||
2931 | .type = HDA_FIXUP_FUNC, | 3359 | .type = HDA_FIXUP_FUNC, |
2932 | .v.func = alc269_fixup_hp_mute_led_mic2, | 3360 | .v.func = alc269_fixup_hp_mute_led_mic2, |
2933 | }, | 3361 | }, |
3362 | [ALC269_FIXUP_HP_GPIO_LED] = { | ||
3363 | .type = HDA_FIXUP_FUNC, | ||
3364 | .v.func = alc269_fixup_hp_gpio_led, | ||
3365 | }, | ||
2934 | [ALC269_FIXUP_INV_DMIC] = { | 3366 | [ALC269_FIXUP_INV_DMIC] = { |
2935 | .type = HDA_FIXUP_FUNC, | 3367 | .type = HDA_FIXUP_FUNC, |
2936 | .v.func = alc_fixup_inv_dmic_0x12, | 3368 | .v.func = alc_fixup_inv_dmic_0x12, |
@@ -2949,6 +3381,59 @@ static const struct hda_fixup alc269_fixups[] = { | |||
2949 | .type = HDA_FIXUP_FUNC, | 3381 | .type = HDA_FIXUP_FUNC, |
2950 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 3382 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
2951 | }, | 3383 | }, |
3384 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { | ||
3385 | .type = HDA_FIXUP_PINS, | ||
3386 | .v.pins = (const struct hda_pintbl[]) { | ||
3387 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
3388 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | ||
3389 | { } | ||
3390 | }, | ||
3391 | .chained = true, | ||
3392 | .chain_id = ALC269_FIXUP_HEADSET_MODE | ||
3393 | }, | ||
3394 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { | ||
3395 | .type = HDA_FIXUP_PINS, | ||
3396 | .v.pins = (const struct hda_pintbl[]) { | ||
3397 | { 0x16, 0x21014020 }, /* dock line out */ | ||
3398 | { 0x19, 0x21a19030 }, /* dock mic */ | ||
3399 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
3400 | { } | ||
3401 | }, | ||
3402 | .chained = true, | ||
3403 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | ||
3404 | }, | ||
3405 | [ALC269_FIXUP_HEADSET_MODE] = { | ||
3406 | .type = HDA_FIXUP_FUNC, | ||
3407 | .v.func = alc_fixup_headset_mode, | ||
3408 | }, | ||
3409 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | ||
3410 | .type = HDA_FIXUP_FUNC, | ||
3411 | .v.func = alc_fixup_headset_mode_no_hp_mic, | ||
3412 | }, | ||
3413 | [ALC269_FIXUP_ASUS_X101_FUNC] = { | ||
3414 | .type = HDA_FIXUP_FUNC, | ||
3415 | .v.func = alc269_fixup_x101_headset_mic, | ||
3416 | }, | ||
3417 | [ALC269_FIXUP_ASUS_X101_VERB] = { | ||
3418 | .type = HDA_FIXUP_VERBS, | ||
3419 | .v.verbs = (const struct hda_verb[]) { | ||
3420 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3421 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | ||
3422 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, | ||
3423 | { } | ||
3424 | }, | ||
3425 | .chained = true, | ||
3426 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC | ||
3427 | }, | ||
3428 | [ALC269_FIXUP_ASUS_X101] = { | ||
3429 | .type = HDA_FIXUP_PINS, | ||
3430 | .v.pins = (const struct hda_pintbl[]) { | ||
3431 | { 0x18, 0x04a1182c }, /* Headset mic */ | ||
3432 | { } | ||
3433 | }, | ||
3434 | .chained = true, | ||
3435 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB | ||
3436 | }, | ||
2952 | [ALC271_FIXUP_AMIC_MIC2] = { | 3437 | [ALC271_FIXUP_AMIC_MIC2] = { |
2953 | .type = HDA_FIXUP_PINS, | 3438 | .type = HDA_FIXUP_PINS, |
2954 | .v.pins = (const struct hda_pintbl[]) { | 3439 | .v.pins = (const struct hda_pintbl[]) { |
@@ -2965,29 +3450,72 @@ static const struct hda_fixup alc269_fixups[] = { | |||
2965 | .chained = true, | 3450 | .chained = true, |
2966 | .chain_id = ALC271_FIXUP_AMIC_MIC2, | 3451 | .chain_id = ALC271_FIXUP_AMIC_MIC2, |
2967 | }, | 3452 | }, |
3453 | [ALC269_FIXUP_ACER_AC700] = { | ||
3454 | .type = HDA_FIXUP_PINS, | ||
3455 | .v.pins = (const struct hda_pintbl[]) { | ||
3456 | { 0x12, 0x99a3092f }, /* int-mic */ | ||
3457 | { 0x14, 0x99130110 }, /* speaker */ | ||
3458 | { 0x18, 0x03a11c20 }, /* mic */ | ||
3459 | { 0x1e, 0x0346101e }, /* SPDIF1 */ | ||
3460 | { 0x21, 0x0321101f }, /* HP out */ | ||
3461 | { } | ||
3462 | }, | ||
3463 | .chained = true, | ||
3464 | .chain_id = ALC271_FIXUP_DMIC, | ||
3465 | }, | ||
3466 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { | ||
3467 | .type = HDA_FIXUP_FUNC, | ||
3468 | .v.func = alc269_fixup_limit_int_mic_boost, | ||
3469 | }, | ||
2968 | }; | 3470 | }; |
2969 | 3471 | ||
2970 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 3472 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
2971 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 3473 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
2972 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 3474 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
3475 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3476 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3477 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3478 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3479 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3480 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3481 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3482 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3483 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3484 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | ||
3485 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3486 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3487 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3488 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3489 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3490 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3491 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3492 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3493 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
3494 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
2973 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 3495 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
3496 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | ||
2974 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 3497 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
2975 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 3498 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
2976 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 3499 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
3500 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | ||
3501 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | ||
2977 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), | 3502 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), |
2978 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), | 3503 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), |
3504 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | ||
2979 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 3505 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
2980 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | 3506 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
2981 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 3507 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
2982 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 3508 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
2983 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 3509 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
2984 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 3510 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
2985 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 3511 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
3512 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | ||
2986 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 3513 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
2987 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 3514 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
2988 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 3515 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
2989 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 3516 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
2990 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 3517 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
3518 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), | ||
2991 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), | 3519 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), |
2992 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), | 3520 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), |
2993 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | 3521 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
@@ -3063,6 +3591,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
3063 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | 3591 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, |
3064 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 3592 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
3065 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 3593 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
3594 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | ||
3066 | {} | 3595 | {} |
3067 | }; | 3596 | }; |
3068 | 3597 | ||
@@ -3131,6 +3660,9 @@ static int patch_alc269(struct hda_codec *codec) | |||
3131 | 3660 | ||
3132 | alc_auto_parse_customize_define(codec); | 3661 | alc_auto_parse_customize_define(codec); |
3133 | 3662 | ||
3663 | if (has_cdefine_beep(codec)) | ||
3664 | spec->gen.beep_nid = 0x01; | ||
3665 | |||
3134 | switch (codec->vendor_id) { | 3666 | switch (codec->vendor_id) { |
3135 | case 0x10ec0269: | 3667 | case 0x10ec0269: |
3136 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 3668 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
@@ -3172,6 +3704,9 @@ static int patch_alc269(struct hda_codec *codec) | |||
3172 | case 0x10ec0292: | 3704 | case 0x10ec0292: |
3173 | spec->codec_variant = ALC269_TYPE_ALC284; | 3705 | spec->codec_variant = ALC269_TYPE_ALC284; |
3174 | break; | 3706 | break; |
3707 | case 0x10ec0286: | ||
3708 | spec->codec_variant = ALC269_TYPE_ALC286; | ||
3709 | break; | ||
3175 | } | 3710 | } |
3176 | 3711 | ||
3177 | /* automatic parse from the BIOS config */ | 3712 | /* automatic parse from the BIOS config */ |
@@ -3179,12 +3714,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
3179 | if (err < 0) | 3714 | if (err < 0) |
3180 | goto error; | 3715 | goto error; |
3181 | 3716 | ||
3182 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { | 3717 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
3183 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
3184 | if (err < 0) | ||
3185 | goto error; | ||
3186 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 3718 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
3187 | } | ||
3188 | 3719 | ||
3189 | codec->patch_ops = alc_patch_ops; | 3720 | codec->patch_ops = alc_patch_ops; |
3190 | #ifdef CONFIG_PM | 3721 | #ifdef CONFIG_PM |
@@ -3292,6 +3823,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
3292 | return err; | 3823 | return err; |
3293 | 3824 | ||
3294 | spec = codec->spec; | 3825 | spec = codec->spec; |
3826 | spec->gen.beep_nid = 0x23; | ||
3295 | 3827 | ||
3296 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | 3828 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
3297 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 3829 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
@@ -3301,12 +3833,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
3301 | if (err < 0) | 3833 | if (err < 0) |
3302 | goto error; | 3834 | goto error; |
3303 | 3835 | ||
3304 | if (!spec->gen.no_analog) { | 3836 | if (!spec->gen.no_analog) |
3305 | err = snd_hda_attach_beep_device(codec, 0x23); | ||
3306 | if (err < 0) | ||
3307 | goto error; | ||
3308 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 3837 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
3309 | } | ||
3310 | 3838 | ||
3311 | codec->patch_ops = alc_patch_ops; | 3839 | codec->patch_ops = alc_patch_ops; |
3312 | #ifdef CONFIG_PM | 3840 | #ifdef CONFIG_PM |
@@ -3387,6 +3915,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
3387 | return err; | 3915 | return err; |
3388 | 3916 | ||
3389 | spec = codec->spec; | 3917 | spec = codec->spec; |
3918 | spec->gen.beep_nid = 0x23; | ||
3390 | 3919 | ||
3391 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | 3920 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
3392 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 3921 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
@@ -3396,12 +3925,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
3396 | if (err < 0) | 3925 | if (err < 0) |
3397 | goto error; | 3926 | goto error; |
3398 | 3927 | ||
3399 | if (!spec->gen.no_analog) { | 3928 | if (!spec->gen.no_analog) |
3400 | err = snd_hda_attach_beep_device(codec, 0x23); | ||
3401 | if (err < 0) | ||
3402 | goto error; | ||
3403 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 3929 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
3404 | } | ||
3405 | 3930 | ||
3406 | codec->patch_ops = alc_patch_ops; | 3931 | codec->patch_ops = alc_patch_ops; |
3407 | 3932 | ||
@@ -3480,6 +4005,8 @@ enum { | |||
3480 | ALC662_FIXUP_NO_JACK_DETECT, | 4005 | ALC662_FIXUP_NO_JACK_DETECT, |
3481 | ALC662_FIXUP_ZOTAC_Z68, | 4006 | ALC662_FIXUP_ZOTAC_Z68, |
3482 | ALC662_FIXUP_INV_DMIC, | 4007 | ALC662_FIXUP_INV_DMIC, |
4008 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, | ||
4009 | ALC668_FIXUP_HEADSET_MODE, | ||
3483 | }; | 4010 | }; |
3484 | 4011 | ||
3485 | static const struct hda_fixup alc662_fixups[] = { | 4012 | static const struct hda_fixup alc662_fixups[] = { |
@@ -3640,6 +4167,20 @@ static const struct hda_fixup alc662_fixups[] = { | |||
3640 | .type = HDA_FIXUP_FUNC, | 4167 | .type = HDA_FIXUP_FUNC, |
3641 | .v.func = alc_fixup_inv_dmic_0x12, | 4168 | .v.func = alc_fixup_inv_dmic_0x12, |
3642 | }, | 4169 | }, |
4170 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { | ||
4171 | .type = HDA_FIXUP_PINS, | ||
4172 | .v.pins = (const struct hda_pintbl[]) { | ||
4173 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ | ||
4174 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ | ||
4175 | { } | ||
4176 | }, | ||
4177 | .chained = true, | ||
4178 | .chain_id = ALC668_FIXUP_HEADSET_MODE | ||
4179 | }, | ||
4180 | [ALC668_FIXUP_HEADSET_MODE] = { | ||
4181 | .type = HDA_FIXUP_FUNC, | ||
4182 | .v.func = alc_fixup_headset_mode_alc668, | ||
4183 | }, | ||
3643 | }; | 4184 | }; |
3644 | 4185 | ||
3645 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 4186 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
@@ -3648,6 +4189,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
3648 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 4189 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
3649 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 4190 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
3650 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 4191 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
4192 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
4193 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | ||
3651 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 4194 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
3652 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 4195 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
3653 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 4196 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
@@ -3784,10 +4327,14 @@ static int patch_alc662(struct hda_codec *codec) | |||
3784 | 4327 | ||
3785 | alc_auto_parse_customize_define(codec); | 4328 | alc_auto_parse_customize_define(codec); |
3786 | 4329 | ||
4330 | if (has_cdefine_beep(codec)) | ||
4331 | spec->gen.beep_nid = 0x01; | ||
4332 | |||
3787 | if ((alc_get_coef0(codec) & (1 << 14)) && | 4333 | if ((alc_get_coef0(codec) & (1 << 14)) && |
3788 | codec->bus->pci->subsystem_vendor == 0x1025 && | 4334 | codec->bus->pci->subsystem_vendor == 0x1025 && |
3789 | spec->cdefine.platform_type == 1) { | 4335 | spec->cdefine.platform_type == 1) { |
3790 | if (alc_codec_rename(codec, "ALC272X") < 0) | 4336 | err = alc_codec_rename(codec, "ALC272X"); |
4337 | if (err < 0) | ||
3791 | goto error; | 4338 | goto error; |
3792 | } | 4339 | } |
3793 | 4340 | ||
@@ -3796,10 +4343,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
3796 | if (err < 0) | 4343 | if (err < 0) |
3797 | goto error; | 4344 | goto error; |
3798 | 4345 | ||
3799 | if (!spec->gen.no_analog && has_cdefine_beep(codec)) { | 4346 | if (!spec->gen.no_analog && spec->gen.beep_nid) { |
3800 | err = snd_hda_attach_beep_device(codec, 0x1); | ||
3801 | if (err < 0) | ||
3802 | goto error; | ||
3803 | switch (codec->vendor_id) { | 4347 | switch (codec->vendor_id) { |
3804 | case 0x10ec0662: | 4348 | case 0x10ec0662: |
3805 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4349 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
@@ -3878,6 +4422,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
3878 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | 4422 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, |
3879 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, | 4423 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, |
3880 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, | 4424 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, |
4425 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, | ||
3881 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 4426 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
3882 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | 4427 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, |
3883 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 4428 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index dafe04ae8c72..1d9d6427e0bf 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -211,7 +211,6 @@ struct sigmatel_spec { | |||
211 | 211 | ||
212 | /* beep widgets */ | 212 | /* beep widgets */ |
213 | hda_nid_t anabeep_nid; | 213 | hda_nid_t anabeep_nid; |
214 | hda_nid_t digbeep_nid; | ||
215 | 214 | ||
216 | /* SPDIF-out mux */ | 215 | /* SPDIF-out mux */ |
217 | const char * const *spdif_labels; | 216 | const char * const *spdif_labels; |
@@ -3529,8 +3528,12 @@ static int stac_parse_auto_config(struct hda_codec *codec) | |||
3529 | { | 3528 | { |
3530 | struct sigmatel_spec *spec = codec->spec; | 3529 | struct sigmatel_spec *spec = codec->spec; |
3531 | int err; | 3530 | int err; |
3531 | int flags = 0; | ||
3532 | 3532 | ||
3533 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); | 3533 | if (spec->headset_jack) |
3534 | flags |= HDA_PINCFG_HEADSET_MIC; | ||
3535 | |||
3536 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, flags); | ||
3534 | if (err < 0) | 3537 | if (err < 0) |
3535 | return err; | 3538 | return err; |
3536 | 3539 | ||
@@ -3560,16 +3563,13 @@ static int stac_parse_auto_config(struct hda_codec *codec) | |||
3560 | 3563 | ||
3561 | /* setup digital beep controls and input device */ | 3564 | /* setup digital beep controls and input device */ |
3562 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 3565 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
3563 | if (spec->digbeep_nid > 0) { | 3566 | if (spec->gen.beep_nid) { |
3564 | hda_nid_t nid = spec->digbeep_nid; | 3567 | hda_nid_t nid = spec->gen.beep_nid; |
3565 | unsigned int caps; | 3568 | unsigned int caps; |
3566 | 3569 | ||
3567 | err = stac_auto_create_beep_ctls(codec, nid); | 3570 | err = stac_auto_create_beep_ctls(codec, nid); |
3568 | if (err < 0) | 3571 | if (err < 0) |
3569 | return err; | 3572 | return err; |
3570 | err = snd_hda_attach_beep_device(codec, nid); | ||
3571 | if (err < 0) | ||
3572 | return err; | ||
3573 | if (codec->beep) { | 3573 | if (codec->beep) { |
3574 | /* IDT/STAC codecs have linear beep tone parameter */ | 3574 | /* IDT/STAC codecs have linear beep tone parameter */ |
3575 | codec->beep->linear_tone = spec->linear_tone_beep; | 3575 | codec->beep->linear_tone = spec->linear_tone_beep; |
@@ -3657,17 +3657,7 @@ static void stac_shutup(struct hda_codec *codec) | |||
3657 | ~spec->eapd_mask); | 3657 | ~spec->eapd_mask); |
3658 | } | 3658 | } |
3659 | 3659 | ||
3660 | static void stac_free(struct hda_codec *codec) | 3660 | #define stac_free snd_hda_gen_free |
3661 | { | ||
3662 | struct sigmatel_spec *spec = codec->spec; | ||
3663 | |||
3664 | if (!spec) | ||
3665 | return; | ||
3666 | |||
3667 | snd_hda_gen_spec_free(&spec->gen); | ||
3668 | kfree(spec); | ||
3669 | snd_hda_detach_beep_device(codec); | ||
3670 | } | ||
3671 | 3661 | ||
3672 | #ifdef CONFIG_PROC_FS | 3662 | #ifdef CONFIG_PROC_FS |
3673 | static void stac92hd_proc_hook(struct snd_info_buffer *buffer, | 3663 | static void stac92hd_proc_hook(struct snd_info_buffer *buffer, |
@@ -3797,6 +3787,7 @@ static int patch_stac9200(struct hda_codec *codec) | |||
3797 | spec->gen.own_eapd_ctl = 1; | 3787 | spec->gen.own_eapd_ctl = 1; |
3798 | 3788 | ||
3799 | codec->patch_ops = stac_patch_ops; | 3789 | codec->patch_ops = stac_patch_ops; |
3790 | codec->power_filter = snd_hda_codec_eapd_power_filter; | ||
3800 | 3791 | ||
3801 | snd_hda_add_verbs(codec, stac9200_eapd_init); | 3792 | snd_hda_add_verbs(codec, stac9200_eapd_init); |
3802 | 3793 | ||
@@ -3884,7 +3875,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
3884 | spec->aloopback_mask = 0x01; | 3875 | spec->aloopback_mask = 0x01; |
3885 | spec->aloopback_shift = 8; | 3876 | spec->aloopback_shift = 8; |
3886 | 3877 | ||
3887 | spec->digbeep_nid = 0x1c; | 3878 | spec->gen.beep_nid = 0x1c; /* digital beep */ |
3888 | 3879 | ||
3889 | /* GPIO0 High = Enable EAPD */ | 3880 | /* GPIO0 High = Enable EAPD */ |
3890 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | 3881 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
@@ -3968,7 +3959,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
3968 | spec->gen.power_down_unused = 1; | 3959 | spec->gen.power_down_unused = 1; |
3969 | spec->gen.mixer_nid = 0x1b; | 3960 | spec->gen.mixer_nid = 0x1b; |
3970 | 3961 | ||
3971 | spec->digbeep_nid = 0x21; | 3962 | spec->gen.beep_nid = 0x21; /* digital beep */ |
3972 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 3963 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
3973 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 3964 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
3974 | spec->default_polarity = -1; /* no default cfg */ | 3965 | spec->default_polarity = -1; /* no default cfg */ |
@@ -4016,7 +4007,7 @@ static int patch_stac92hd95(struct hda_codec *codec) | |||
4016 | spec->gen.own_eapd_ctl = 1; | 4007 | spec->gen.own_eapd_ctl = 1; |
4017 | spec->gen.power_down_unused = 1; | 4008 | spec->gen.power_down_unused = 1; |
4018 | 4009 | ||
4019 | spec->digbeep_nid = 0x19; | 4010 | spec->gen.beep_nid = 0x19; /* digital beep */ |
4020 | spec->pwr_nids = stac92hd95_pwr_nids; | 4011 | spec->pwr_nids = stac92hd95_pwr_nids; |
4021 | spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); | 4012 | spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids); |
4022 | spec->default_polarity = -1; /* no default cfg */ | 4013 | spec->default_polarity = -1; /* no default cfg */ |
@@ -4091,7 +4082,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
4091 | spec->aloopback_shift = 0; | 4082 | spec->aloopback_shift = 0; |
4092 | 4083 | ||
4093 | spec->powerdown_adcs = 1; | 4084 | spec->powerdown_adcs = 1; |
4094 | spec->digbeep_nid = 0x26; | 4085 | spec->gen.beep_nid = 0x26; /* digital beep */ |
4095 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 4086 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
4096 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 4087 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
4097 | 4088 | ||
@@ -4173,7 +4164,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
4173 | spec->have_spdif_mux = 1; | 4164 | spec->have_spdif_mux = 1; |
4174 | spec->spdif_labels = stac927x_spdif_labels; | 4165 | spec->spdif_labels = stac927x_spdif_labels; |
4175 | 4166 | ||
4176 | spec->digbeep_nid = 0x23; | 4167 | spec->gen.beep_nid = 0x23; /* digital beep */ |
4177 | 4168 | ||
4178 | /* GPIO0 High = Enable EAPD */ | 4169 | /* GPIO0 High = Enable EAPD */ |
4179 | spec->eapd_mask = spec->gpio_mask = 0x01; | 4170 | spec->eapd_mask = spec->gpio_mask = 0x01; |
@@ -4232,7 +4223,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
4232 | spec->gen.own_eapd_ctl = 1; | 4223 | spec->gen.own_eapd_ctl = 1; |
4233 | spec->have_spdif_mux = 1; | 4224 | spec->have_spdif_mux = 1; |
4234 | 4225 | ||
4235 | spec->digbeep_nid = 0x23; | 4226 | spec->gen.beep_nid = 0x23; /* digital beep */ |
4236 | 4227 | ||
4237 | snd_hda_add_verbs(codec, stac9205_core_init); | 4228 | snd_hda_add_verbs(codec, stac9205_core_init); |
4238 | spec->aloopback_ctl = &stac9205_loopback; | 4229 | spec->aloopback_ctl = &stac9205_loopback; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index c35338a8771d..e0dadcf2030d 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -626,11 +626,31 @@ static void via_set_jack_unsol_events(struct hda_codec *codec) | |||
626 | } | 626 | } |
627 | } | 627 | } |
628 | 628 | ||
629 | static const struct badness_table via_main_out_badness = { | ||
630 | .no_primary_dac = 0x10000, | ||
631 | .no_dac = 0x4000, | ||
632 | .shared_primary = 0x10000, | ||
633 | .shared_surr = 0x20, | ||
634 | .shared_clfe = 0x20, | ||
635 | .shared_surr_main = 0x20, | ||
636 | }; | ||
637 | static const struct badness_table via_extra_out_badness = { | ||
638 | .no_primary_dac = 0x4000, | ||
639 | .no_dac = 0x4000, | ||
640 | .shared_primary = 0x12, | ||
641 | .shared_surr = 0x20, | ||
642 | .shared_clfe = 0x20, | ||
643 | .shared_surr_main = 0x10, | ||
644 | }; | ||
645 | |||
629 | static int via_parse_auto_config(struct hda_codec *codec) | 646 | static int via_parse_auto_config(struct hda_codec *codec) |
630 | { | 647 | { |
631 | struct via_spec *spec = codec->spec; | 648 | struct via_spec *spec = codec->spec; |
632 | int err; | 649 | int err; |
633 | 650 | ||
651 | spec->gen.main_out_badness = &via_main_out_badness; | ||
652 | spec->gen.extra_out_badness = &via_extra_out_badness; | ||
653 | |||
634 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); | 654 | err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); |
635 | if (err < 0) | 655 | if (err < 0) |
636 | return err; | 656 | return err; |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 223c3d9cc69e..9ea05e956474 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -969,6 +969,7 @@ static int snd_hdspm_create_pcm(struct snd_card *card, | |||
969 | struct hdspm *hdspm); | 969 | struct hdspm *hdspm); |
970 | 970 | ||
971 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); | 971 | static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); |
972 | static inline int hdspm_get_pll_freq(struct hdspm *hdspm); | ||
972 | static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); | 973 | static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); |
973 | static int hdspm_autosync_ref(struct hdspm *hdspm); | 974 | static int hdspm_autosync_ref(struct hdspm *hdspm); |
974 | static int snd_hdspm_set_defaults(struct hdspm *hdspm); | 975 | static int snd_hdspm_set_defaults(struct hdspm *hdspm); |
@@ -1075,6 +1076,20 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm) | |||
1075 | return ret; | 1076 | return ret; |
1076 | } | 1077 | } |
1077 | 1078 | ||
1079 | /* round arbitary sample rates to commonly known rates */ | ||
1080 | static int hdspm_round_frequency(int rate) | ||
1081 | { | ||
1082 | if (rate < 38050) | ||
1083 | return 32000; | ||
1084 | if (rate < 46008) | ||
1085 | return 44100; | ||
1086 | else | ||
1087 | return 48000; | ||
1088 | } | ||
1089 | |||
1090 | static int hdspm_tco_sync_check(struct hdspm *hdspm); | ||
1091 | static int hdspm_sync_in_sync_check(struct hdspm *hdspm); | ||
1092 | |||
1078 | /* check for external sample rate */ | 1093 | /* check for external sample rate */ |
1079 | static int hdspm_external_sample_rate(struct hdspm *hdspm) | 1094 | static int hdspm_external_sample_rate(struct hdspm *hdspm) |
1080 | { | 1095 | { |
@@ -1216,22 +1231,45 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
1216 | break; | 1231 | break; |
1217 | } | 1232 | } |
1218 | 1233 | ||
1219 | /* QS and DS rates normally can not be detected | 1234 | } /* endif HDSPM_madiLock */ |
1220 | * automatically by the card. Only exception is MADI | 1235 | |
1221 | * in 96k frame mode. | 1236 | /* check sample rate from TCO or SYNC_IN */ |
1222 | * | 1237 | { |
1223 | * So if we read SS values (32 .. 48k), check for | 1238 | bool is_valid_input = 0; |
1224 | * user-provided DS/QS bits in the control register | 1239 | bool has_sync = 0; |
1225 | * and multiply the base frequency accordingly. | 1240 | |
1226 | */ | 1241 | syncref = hdspm_autosync_ref(hdspm); |
1227 | if (rate <= 48000) { | 1242 | if (HDSPM_AUTOSYNC_FROM_TCO == syncref) { |
1228 | if (hdspm->control_register & HDSPM_QuadSpeed) | 1243 | is_valid_input = 1; |
1229 | rate *= 4; | 1244 | has_sync = (HDSPM_SYNC_CHECK_SYNC == |
1230 | else if (hdspm->control_register & | 1245 | hdspm_tco_sync_check(hdspm)); |
1231 | HDSPM_DoubleSpeed) | 1246 | } else if (HDSPM_AUTOSYNC_FROM_SYNC_IN == syncref) { |
1232 | rate *= 2; | 1247 | is_valid_input = 1; |
1248 | has_sync = (HDSPM_SYNC_CHECK_SYNC == | ||
1249 | hdspm_sync_in_sync_check(hdspm)); | ||
1250 | } | ||
1251 | |||
1252 | if (is_valid_input && has_sync) { | ||
1253 | rate = hdspm_round_frequency( | ||
1254 | hdspm_get_pll_freq(hdspm)); | ||
1233 | } | 1255 | } |
1234 | } | 1256 | } |
1257 | |||
1258 | /* QS and DS rates normally can not be detected | ||
1259 | * automatically by the card. Only exception is MADI | ||
1260 | * in 96k frame mode. | ||
1261 | * | ||
1262 | * So if we read SS values (32 .. 48k), check for | ||
1263 | * user-provided DS/QS bits in the control register | ||
1264 | * and multiply the base frequency accordingly. | ||
1265 | */ | ||
1266 | if (rate <= 48000) { | ||
1267 | if (hdspm->control_register & HDSPM_QuadSpeed) | ||
1268 | rate *= 4; | ||
1269 | else if (hdspm->control_register & | ||
1270 | HDSPM_DoubleSpeed) | ||
1271 | rate *= 2; | ||
1272 | } | ||
1235 | break; | 1273 | break; |
1236 | } | 1274 | } |
1237 | 1275 | ||
@@ -1979,16 +2017,25 @@ static void hdspm_midi_tasklet(unsigned long arg) | |||
1979 | /* get the system sample rate which is set */ | 2017 | /* get the system sample rate which is set */ |
1980 | 2018 | ||
1981 | 2019 | ||
2020 | static inline int hdspm_get_pll_freq(struct hdspm *hdspm) | ||
2021 | { | ||
2022 | unsigned int period, rate; | ||
2023 | |||
2024 | period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); | ||
2025 | rate = hdspm_calc_dds_value(hdspm, period); | ||
2026 | |||
2027 | return rate; | ||
2028 | } | ||
2029 | |||
1982 | /** | 2030 | /** |
1983 | * Calculate the real sample rate from the | 2031 | * Calculate the real sample rate from the |
1984 | * current DDS value. | 2032 | * current DDS value. |
1985 | **/ | 2033 | **/ |
1986 | static int hdspm_get_system_sample_rate(struct hdspm *hdspm) | 2034 | static int hdspm_get_system_sample_rate(struct hdspm *hdspm) |
1987 | { | 2035 | { |
1988 | unsigned int period, rate; | 2036 | unsigned int rate; |
1989 | 2037 | ||
1990 | period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); | 2038 | rate = hdspm_get_pll_freq(hdspm); |
1991 | rate = hdspm_calc_dds_value(hdspm, period); | ||
1992 | 2039 | ||
1993 | if (rate > 207000) { | 2040 | if (rate > 207000) { |
1994 | /* Unreasonable high sample rate as seen on PCI MADI cards. */ | 2041 | /* Unreasonable high sample rate as seen on PCI MADI cards. */ |
@@ -2128,6 +2175,16 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) | |||
2128 | return (status >> (idx*4)) & 0xF; | 2175 | return (status >> (idx*4)) & 0xF; |
2129 | } | 2176 | } |
2130 | 2177 | ||
2178 | #define ENUMERATED_CTL_INFO(info, texts) \ | ||
2179 | { \ | ||
2180 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ | ||
2181 | uinfo->count = 1; \ | ||
2182 | uinfo->value.enumerated.items = ARRAY_SIZE(texts); \ | ||
2183 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \ | ||
2184 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \ | ||
2185 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \ | ||
2186 | } | ||
2187 | |||
2131 | 2188 | ||
2132 | 2189 | ||
2133 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ | 2190 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ |
@@ -2143,14 +2200,7 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) | |||
2143 | static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, | 2200 | static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, |
2144 | struct snd_ctl_elem_info *uinfo) | 2201 | struct snd_ctl_elem_info *uinfo) |
2145 | { | 2202 | { |
2146 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2203 | ENUMERATED_CTL_INFO(uinfo, texts_freq); |
2147 | uinfo->count = 1; | ||
2148 | uinfo->value.enumerated.items = 10; | ||
2149 | |||
2150 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2151 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
2152 | strcpy(uinfo->value.enumerated.name, | ||
2153 | texts_freq[uinfo->value.enumerated.item]); | ||
2154 | return 0; | 2204 | return 0; |
2155 | } | 2205 | } |
2156 | 2206 | ||
@@ -2316,15 +2366,7 @@ static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, | |||
2316 | struct snd_ctl_elem_info *uinfo) | 2366 | struct snd_ctl_elem_info *uinfo) |
2317 | { | 2367 | { |
2318 | static char *texts[] = { "Master", "AutoSync" }; | 2368 | static char *texts[] = { "Master", "AutoSync" }; |
2319 | 2369 | ENUMERATED_CTL_INFO(uinfo, texts); | |
2320 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2321 | uinfo->count = 1; | ||
2322 | uinfo->value.enumerated.items = 2; | ||
2323 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2324 | uinfo->value.enumerated.item = | ||
2325 | uinfo->value.enumerated.items - 1; | ||
2326 | strcpy(uinfo->value.enumerated.name, | ||
2327 | texts[uinfo->value.enumerated.item]); | ||
2328 | return 0; | 2370 | return 0; |
2329 | } | 2371 | } |
2330 | 2372 | ||
@@ -2888,6 +2930,112 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, | |||
2888 | return 0; | 2930 | return 0; |
2889 | } | 2931 | } |
2890 | 2932 | ||
2933 | |||
2934 | |||
2935 | #define HDSPM_TCO_VIDEO_INPUT_FORMAT(xname, xindex) \ | ||
2936 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2937 | .name = xname, \ | ||
2938 | .access = SNDRV_CTL_ELEM_ACCESS_READ |\ | ||
2939 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
2940 | .info = snd_hdspm_info_tco_video_input_format, \ | ||
2941 | .get = snd_hdspm_get_tco_video_input_format, \ | ||
2942 | } | ||
2943 | |||
2944 | static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol, | ||
2945 | struct snd_ctl_elem_info *uinfo) | ||
2946 | { | ||
2947 | static char *texts[] = {"No video", "NTSC", "PAL"}; | ||
2948 | ENUMERATED_CTL_INFO(uinfo, texts); | ||
2949 | return 0; | ||
2950 | } | ||
2951 | |||
2952 | static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol, | ||
2953 | struct snd_ctl_elem_value *ucontrol) | ||
2954 | { | ||
2955 | u32 status; | ||
2956 | int ret = 0; | ||
2957 | |||
2958 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
2959 | status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); | ||
2960 | switch (status & (HDSPM_TCO1_Video_Input_Format_NTSC | | ||
2961 | HDSPM_TCO1_Video_Input_Format_PAL)) { | ||
2962 | case HDSPM_TCO1_Video_Input_Format_NTSC: | ||
2963 | /* ntsc */ | ||
2964 | ret = 1; | ||
2965 | break; | ||
2966 | case HDSPM_TCO1_Video_Input_Format_PAL: | ||
2967 | /* pal */ | ||
2968 | ret = 2; | ||
2969 | break; | ||
2970 | default: | ||
2971 | /* no video */ | ||
2972 | ret = 0; | ||
2973 | break; | ||
2974 | } | ||
2975 | ucontrol->value.enumerated.item[0] = ret; | ||
2976 | return 0; | ||
2977 | } | ||
2978 | |||
2979 | |||
2980 | |||
2981 | #define HDSPM_TCO_LTC_FRAMES(xname, xindex) \ | ||
2982 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2983 | .name = xname, \ | ||
2984 | .access = SNDRV_CTL_ELEM_ACCESS_READ |\ | ||
2985 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
2986 | .info = snd_hdspm_info_tco_ltc_frames, \ | ||
2987 | .get = snd_hdspm_get_tco_ltc_frames, \ | ||
2988 | } | ||
2989 | |||
2990 | static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol, | ||
2991 | struct snd_ctl_elem_info *uinfo) | ||
2992 | { | ||
2993 | static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", | ||
2994 | "30 fps"}; | ||
2995 | ENUMERATED_CTL_INFO(uinfo, texts); | ||
2996 | return 0; | ||
2997 | } | ||
2998 | |||
2999 | static int hdspm_tco_ltc_frames(struct hdspm *hdspm) | ||
3000 | { | ||
3001 | u32 status; | ||
3002 | int ret = 0; | ||
3003 | |||
3004 | status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); | ||
3005 | if (status & HDSPM_TCO1_LTC_Input_valid) { | ||
3006 | switch (status & (HDSPM_TCO1_LTC_Format_LSB | | ||
3007 | HDSPM_TCO1_LTC_Format_MSB)) { | ||
3008 | case 0: | ||
3009 | /* 24 fps */ | ||
3010 | ret = 1; | ||
3011 | break; | ||
3012 | case HDSPM_TCO1_LTC_Format_LSB: | ||
3013 | /* 25 fps */ | ||
3014 | ret = 2; | ||
3015 | break; | ||
3016 | case HDSPM_TCO1_LTC_Format_MSB: | ||
3017 | /* 25 fps */ | ||
3018 | ret = 3; | ||
3019 | break; | ||
3020 | default: | ||
3021 | /* 30 fps */ | ||
3022 | ret = 4; | ||
3023 | break; | ||
3024 | } | ||
3025 | } | ||
3026 | |||
3027 | return ret; | ||
3028 | } | ||
3029 | |||
3030 | static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol, | ||
3031 | struct snd_ctl_elem_value *ucontrol) | ||
3032 | { | ||
3033 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | ||
3034 | |||
3035 | ucontrol->value.enumerated.item[0] = hdspm_tco_ltc_frames(hdspm); | ||
3036 | return 0; | ||
3037 | } | ||
3038 | |||
2891 | #define HDSPM_TOGGLE_SETTING(xname, xindex) \ | 3039 | #define HDSPM_TOGGLE_SETTING(xname, xindex) \ |
2892 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 3040 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2893 | .name = xname, \ | 3041 | .name = xname, \ |
@@ -2974,17 +3122,7 @@ static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, | |||
2974 | struct snd_ctl_elem_info *uinfo) | 3122 | struct snd_ctl_elem_info *uinfo) |
2975 | { | 3123 | { |
2976 | static char *texts[] = { "optical", "coaxial" }; | 3124 | static char *texts[] = { "optical", "coaxial" }; |
2977 | 3125 | ENUMERATED_CTL_INFO(uinfo, texts); | |
2978 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2979 | uinfo->count = 1; | ||
2980 | uinfo->value.enumerated.items = 2; | ||
2981 | |||
2982 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
2983 | uinfo->value.enumerated.item = | ||
2984 | uinfo->value.enumerated.items - 1; | ||
2985 | strcpy(uinfo->value.enumerated.name, | ||
2986 | texts[uinfo->value.enumerated.item]); | ||
2987 | |||
2988 | return 0; | 3126 | return 0; |
2989 | } | 3127 | } |
2990 | 3128 | ||
@@ -3046,17 +3184,7 @@ static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, | |||
3046 | struct snd_ctl_elem_info *uinfo) | 3184 | struct snd_ctl_elem_info *uinfo) |
3047 | { | 3185 | { |
3048 | static char *texts[] = { "Single", "Double" }; | 3186 | static char *texts[] = { "Single", "Double" }; |
3049 | 3187 | ENUMERATED_CTL_INFO(uinfo, texts); | |
3050 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3051 | uinfo->count = 1; | ||
3052 | uinfo->value.enumerated.items = 2; | ||
3053 | |||
3054 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3055 | uinfo->value.enumerated.item = | ||
3056 | uinfo->value.enumerated.items - 1; | ||
3057 | strcpy(uinfo->value.enumerated.name, | ||
3058 | texts[uinfo->value.enumerated.item]); | ||
3059 | |||
3060 | return 0; | 3188 | return 0; |
3061 | } | 3189 | } |
3062 | 3190 | ||
@@ -3129,17 +3257,7 @@ static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, | |||
3129 | struct snd_ctl_elem_info *uinfo) | 3257 | struct snd_ctl_elem_info *uinfo) |
3130 | { | 3258 | { |
3131 | static char *texts[] = { "Single", "Double", "Quad" }; | 3259 | static char *texts[] = { "Single", "Double", "Quad" }; |
3132 | 3260 | ENUMERATED_CTL_INFO(uinfo, texts); | |
3133 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3134 | uinfo->count = 1; | ||
3135 | uinfo->value.enumerated.items = 3; | ||
3136 | |||
3137 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3138 | uinfo->value.enumerated.item = | ||
3139 | uinfo->value.enumerated.items - 1; | ||
3140 | strcpy(uinfo->value.enumerated.name, | ||
3141 | texts[uinfo->value.enumerated.item]); | ||
3142 | |||
3143 | return 0; | 3261 | return 0; |
3144 | } | 3262 | } |
3145 | 3263 | ||
@@ -3215,17 +3333,7 @@ static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, | |||
3215 | struct snd_ctl_elem_info *uinfo) | 3333 | struct snd_ctl_elem_info *uinfo) |
3216 | { | 3334 | { |
3217 | static char *texts[] = { "Single", "Double", "Quad" }; | 3335 | static char *texts[] = { "Single", "Double", "Quad" }; |
3218 | 3336 | ENUMERATED_CTL_INFO(uinfo, texts); | |
3219 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3220 | uinfo->count = 1; | ||
3221 | uinfo->value.enumerated.items = 3; | ||
3222 | |||
3223 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3224 | uinfo->value.enumerated.item = | ||
3225 | uinfo->value.enumerated.items - 1; | ||
3226 | strcpy(uinfo->value.enumerated.name, | ||
3227 | texts[uinfo->value.enumerated.item]); | ||
3228 | |||
3229 | return 0; | 3337 | return 0; |
3230 | } | 3338 | } |
3231 | 3339 | ||
@@ -3445,19 +3553,30 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, | |||
3445 | .get = snd_hdspm_get_sync_check \ | 3553 | .get = snd_hdspm_get_sync_check \ |
3446 | } | 3554 | } |
3447 | 3555 | ||
3556 | #define HDSPM_TCO_LOCK_CHECK(xname, xindex) \ | ||
3557 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
3558 | .name = xname, \ | ||
3559 | .private_value = xindex, \ | ||
3560 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
3561 | .info = snd_hdspm_tco_info_lock_check, \ | ||
3562 | .get = snd_hdspm_get_sync_check \ | ||
3563 | } | ||
3564 | |||
3565 | |||
3448 | 3566 | ||
3449 | static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, | 3567 | static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, |
3450 | struct snd_ctl_elem_info *uinfo) | 3568 | struct snd_ctl_elem_info *uinfo) |
3451 | { | 3569 | { |
3452 | static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; | 3570 | static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; |
3453 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3571 | ENUMERATED_CTL_INFO(uinfo, texts); |
3454 | uinfo->count = 1; | 3572 | return 0; |
3455 | uinfo->value.enumerated.items = 4; | 3573 | } |
3456 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | 3574 | |
3457 | uinfo->value.enumerated.item = | 3575 | static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol, |
3458 | uinfo->value.enumerated.items - 1; | 3576 | struct snd_ctl_elem_info *uinfo) |
3459 | strcpy(uinfo->value.enumerated.name, | 3577 | { |
3460 | texts[uinfo->value.enumerated.item]); | 3578 | static char *texts[] = { "No Lock", "Lock" }; |
3579 | ENUMERATED_CTL_INFO(uinfo, texts); | ||
3461 | return 0; | 3580 | return 0; |
3462 | } | 3581 | } |
3463 | 3582 | ||
@@ -3590,6 +3709,14 @@ static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx) | |||
3590 | return 0; | 3709 | return 0; |
3591 | } | 3710 | } |
3592 | 3711 | ||
3712 | static int hdspm_tco_input_check(struct hdspm *hdspm, u32 mask) | ||
3713 | { | ||
3714 | u32 status; | ||
3715 | status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); | ||
3716 | |||
3717 | return (status & mask) ? 1 : 0; | ||
3718 | } | ||
3719 | |||
3593 | 3720 | ||
3594 | static int hdspm_tco_sync_check(struct hdspm *hdspm) | 3721 | static int hdspm_tco_sync_check(struct hdspm *hdspm) |
3595 | { | 3722 | { |
@@ -3697,6 +3824,22 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, | |||
3697 | 3824 | ||
3698 | } | 3825 | } |
3699 | 3826 | ||
3827 | if (hdspm->tco) { | ||
3828 | switch (kcontrol->private_value) { | ||
3829 | case 11: | ||
3830 | /* Check TCO for lock state of its current input */ | ||
3831 | val = hdspm_tco_input_check(hdspm, HDSPM_TCO1_TCO_lock); | ||
3832 | break; | ||
3833 | case 12: | ||
3834 | /* Check TCO for valid time code on LTC input. */ | ||
3835 | val = hdspm_tco_input_check(hdspm, | ||
3836 | HDSPM_TCO1_LTC_Input_valid); | ||
3837 | break; | ||
3838 | default: | ||
3839 | break; | ||
3840 | } | ||
3841 | } | ||
3842 | |||
3700 | if (-1 == val) | 3843 | if (-1 == val) |
3701 | val = 3; | 3844 | val = 3; |
3702 | 3845 | ||
@@ -3813,17 +3956,7 @@ static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, | |||
3813 | struct snd_ctl_elem_info *uinfo) | 3956 | struct snd_ctl_elem_info *uinfo) |
3814 | { | 3957 | { |
3815 | static char *texts[] = { "44.1 kHz", "48 kHz" }; | 3958 | static char *texts[] = { "44.1 kHz", "48 kHz" }; |
3816 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 3959 | ENUMERATED_CTL_INFO(uinfo, texts); |
3817 | uinfo->count = 1; | ||
3818 | uinfo->value.enumerated.items = 2; | ||
3819 | |||
3820 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3821 | uinfo->value.enumerated.item = | ||
3822 | uinfo->value.enumerated.items - 1; | ||
3823 | |||
3824 | strcpy(uinfo->value.enumerated.name, | ||
3825 | texts[uinfo->value.enumerated.item]); | ||
3826 | |||
3827 | return 0; | 3960 | return 0; |
3828 | } | 3961 | } |
3829 | 3962 | ||
@@ -3869,17 +4002,7 @@ static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, | |||
3869 | struct snd_ctl_elem_info *uinfo) | 4002 | struct snd_ctl_elem_info *uinfo) |
3870 | { | 4003 | { |
3871 | static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; | 4004 | static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; |
3872 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 4005 | ENUMERATED_CTL_INFO(uinfo, texts); |
3873 | uinfo->count = 1; | ||
3874 | uinfo->value.enumerated.items = 5; | ||
3875 | |||
3876 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3877 | uinfo->value.enumerated.item = | ||
3878 | uinfo->value.enumerated.items - 1; | ||
3879 | |||
3880 | strcpy(uinfo->value.enumerated.name, | ||
3881 | texts[uinfo->value.enumerated.item]); | ||
3882 | |||
3883 | return 0; | 4006 | return 0; |
3884 | } | 4007 | } |
3885 | 4008 | ||
@@ -3924,17 +4047,7 @@ static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, | |||
3924 | struct snd_ctl_elem_info *uinfo) | 4047 | struct snd_ctl_elem_info *uinfo) |
3925 | { | 4048 | { |
3926 | static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; | 4049 | static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; |
3927 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 4050 | ENUMERATED_CTL_INFO(uinfo, texts); |
3928 | uinfo->count = 1; | ||
3929 | uinfo->value.enumerated.items = 3; | ||
3930 | |||
3931 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3932 | uinfo->value.enumerated.item = | ||
3933 | uinfo->value.enumerated.items - 1; | ||
3934 | |||
3935 | strcpy(uinfo->value.enumerated.name, | ||
3936 | texts[uinfo->value.enumerated.item]); | ||
3937 | |||
3938 | return 0; | 4051 | return 0; |
3939 | } | 4052 | } |
3940 | 4053 | ||
@@ -3981,17 +4094,7 @@ static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, | |||
3981 | { | 4094 | { |
3982 | static char *texts[] = { "24 fps", "25 fps", "29.97fps", | 4095 | static char *texts[] = { "24 fps", "25 fps", "29.97fps", |
3983 | "29.97 dfps", "30 fps", "30 dfps" }; | 4096 | "29.97 dfps", "30 fps", "30 dfps" }; |
3984 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 4097 | ENUMERATED_CTL_INFO(uinfo, texts); |
3985 | uinfo->count = 1; | ||
3986 | uinfo->value.enumerated.items = 6; | ||
3987 | |||
3988 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
3989 | uinfo->value.enumerated.item = | ||
3990 | uinfo->value.enumerated.items - 1; | ||
3991 | |||
3992 | strcpy(uinfo->value.enumerated.name, | ||
3993 | texts[uinfo->value.enumerated.item]); | ||
3994 | |||
3995 | return 0; | 4098 | return 0; |
3996 | } | 4099 | } |
3997 | 4100 | ||
@@ -4037,17 +4140,7 @@ static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, | |||
4037 | struct snd_ctl_elem_info *uinfo) | 4140 | struct snd_ctl_elem_info *uinfo) |
4038 | { | 4141 | { |
4039 | static char *texts[] = { "LTC", "Video", "WCK" }; | 4142 | static char *texts[] = { "LTC", "Video", "WCK" }; |
4040 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 4143 | ENUMERATED_CTL_INFO(uinfo, texts); |
4041 | uinfo->count = 1; | ||
4042 | uinfo->value.enumerated.items = 3; | ||
4043 | |||
4044 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
4045 | uinfo->value.enumerated.item = | ||
4046 | uinfo->value.enumerated.items - 1; | ||
4047 | |||
4048 | strcpy(uinfo->value.enumerated.name, | ||
4049 | texts[uinfo->value.enumerated.item]); | ||
4050 | |||
4051 | return 0; | 4144 | return 0; |
4052 | } | 4145 | } |
4053 | 4146 | ||
@@ -4145,6 +4238,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { | |||
4145 | HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), | 4238 | HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), |
4146 | HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut), | 4239 | HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut), |
4147 | HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch), | 4240 | HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch), |
4241 | HDSPM_TOGGLE_SETTING("Disable 96K frames", HDSPM_SMUX), | ||
4148 | HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms), | 4242 | HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms), |
4149 | HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp), | 4243 | HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp), |
4150 | HDSPM_INPUT_SELECT("Input Select", 0), | 4244 | HDSPM_INPUT_SELECT("Input Select", 0), |
@@ -4272,7 +4366,11 @@ static struct snd_kcontrol_new snd_hdspm_controls_tco[] = { | |||
4272 | HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), | 4366 | HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), |
4273 | HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0), | 4367 | HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0), |
4274 | HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0), | 4368 | HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0), |
4275 | HDSPM_TCO_WORD_TERM("TCO Word Term", 0) | 4369 | HDSPM_TCO_WORD_TERM("TCO Word Term", 0), |
4370 | HDSPM_TCO_LOCK_CHECK("TCO Input Check", 11), | ||
4371 | HDSPM_TCO_LOCK_CHECK("TCO LTC Valid", 12), | ||
4372 | HDSPM_TCO_LTC_FRAMES("TCO Detected Frame Rate", 0), | ||
4373 | HDSPM_TCO_VIDEO_INPUT_FORMAT("Video Input Format", 0) | ||
4276 | }; | 4374 | }; |
4277 | 4375 | ||
4278 | 4376 | ||
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 5da8ca7aee05..9e675c76436c 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -29,6 +29,10 @@ config SND_SOC_AC97_BUS | |||
29 | config SND_SOC_DMAENGINE_PCM | 29 | config SND_SOC_DMAENGINE_PCM |
30 | bool | 30 | bool |
31 | 31 | ||
32 | config SND_SOC_GENERIC_DMAENGINE_PCM | ||
33 | bool | ||
34 | select SND_SOC_DMAENGINE_PCM | ||
35 | |||
32 | # All the supported SoCs | 36 | # All the supported SoCs |
33 | source "sound/soc/atmel/Kconfig" | 37 | source "sound/soc/atmel/Kconfig" |
34 | source "sound/soc/au1x/Kconfig" | 38 | source "sound/soc/au1x/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 99f32f7c0692..197b6ae54c8d 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -5,6 +5,10 @@ ifneq ($(CONFIG_SND_SOC_DMAENGINE_PCM),) | |||
5 | snd-soc-core-objs += soc-dmaengine-pcm.o | 5 | snd-soc-core-objs += soc-dmaengine-pcm.o |
6 | endif | 6 | endif |
7 | 7 | ||
8 | ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) | ||
9 | snd-soc-core-objs += soc-generic-dmaengine-pcm.o | ||
10 | endif | ||
11 | |||
8 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o | 12 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o |
9 | obj-$(CONFIG_SND_SOC) += codecs/ | 13 | obj-$(CONFIG_SND_SOC) += codecs/ |
10 | obj-$(CONFIG_SND_SOC) += generic/ | 14 | obj-$(CONFIG_SND_SOC) += generic/ |
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 30184a4a147a..1d38fd0bc4e2 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c | |||
@@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { | |||
67 | static void atmel_pcm_dma_irq(u32 ssc_sr, | 67 | static void atmel_pcm_dma_irq(u32 ssc_sr, |
68 | struct snd_pcm_substream *substream) | 68 | struct snd_pcm_substream *substream) |
69 | { | 69 | { |
70 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
70 | struct atmel_pcm_dma_params *prtd; | 71 | struct atmel_pcm_dma_params *prtd; |
71 | 72 | ||
72 | prtd = snd_dmaengine_pcm_get_data(substream); | 73 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
73 | 74 | ||
74 | if (ssc_sr & prtd->mask->ssc_error) { | 75 | if (ssc_sr & prtd->mask->ssc_error) { |
75 | if (snd_pcm_running(substream)) | 76 | if (snd_pcm_running(substream)) |
@@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave) | |||
104 | } | 105 | } |
105 | 106 | ||
106 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | 107 | static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, |
107 | struct snd_pcm_hw_params *params) | 108 | struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) |
108 | { | 109 | { |
109 | struct atmel_pcm_dma_params *prtd; | ||
110 | struct ssc_device *ssc; | 110 | struct ssc_device *ssc; |
111 | struct dma_chan *dma_chan; | 111 | struct dma_chan *dma_chan; |
112 | struct dma_slave_config slave_config; | 112 | struct dma_slave_config slave_config; |
113 | int ret; | 113 | int ret; |
114 | 114 | ||
115 | prtd = snd_dmaengine_pcm_get_data(substream); | ||
116 | ssc = prtd->ssc; | 115 | ssc = prtd->ssc; |
117 | 116 | ||
118 | ret = snd_hwparams_to_dma_slave_config(substream, params, | 117 | ret = snd_hwparams_to_dma_slave_config(substream, params, |
@@ -130,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, | |||
130 | slave_config.src_maxburst = 1; | 129 | slave_config.src_maxburst = 1; |
131 | } | 130 | } |
132 | 131 | ||
133 | slave_config.device_fc = false; | ||
134 | |||
135 | dma_chan = snd_dmaengine_pcm_get_chan(substream); | 132 | dma_chan = snd_dmaengine_pcm_get_chan(substream); |
136 | if (dmaengine_slave_config(dma_chan, &slave_config)) { | 133 | if (dmaengine_slave_config(dma_chan, &slave_config)) { |
137 | pr_err("atmel-pcm: failed to configure dma channel\n"); | 134 | pr_err("atmel-pcm: failed to configure dma channel\n"); |
@@ -158,15 +155,13 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | |||
158 | if (ssc->pdev) | 155 | if (ssc->pdev) |
159 | sdata = ssc->pdev->dev.platform_data; | 156 | sdata = ssc->pdev->dev.platform_data; |
160 | 157 | ||
161 | ret = snd_dmaengine_pcm_open(substream, filter, sdata); | 158 | ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata); |
162 | if (ret) { | 159 | if (ret) { |
163 | pr_err("atmel-pcm: dmaengine pcm open failed\n"); | 160 | pr_err("atmel-pcm: dmaengine pcm open failed\n"); |
164 | return -EINVAL; | 161 | return -EINVAL; |
165 | } | 162 | } |
166 | 163 | ||
167 | snd_dmaengine_pcm_set_data(substream, prtd); | 164 | ret = atmel_pcm_configure_dma(substream, params, prtd); |
168 | |||
169 | ret = atmel_pcm_configure_dma(substream, params); | ||
170 | if (ret) { | 165 | if (ret) { |
171 | pr_err("atmel-pcm: failed to configure dmai\n"); | 166 | pr_err("atmel-pcm: failed to configure dmai\n"); |
172 | goto err; | 167 | goto err; |
@@ -176,15 +171,16 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | |||
176 | 171 | ||
177 | return 0; | 172 | return 0; |
178 | err: | 173 | err: |
179 | snd_dmaengine_pcm_close(substream); | 174 | snd_dmaengine_pcm_close_release_chan(substream); |
180 | return ret; | 175 | return ret; |
181 | } | 176 | } |
182 | 177 | ||
183 | static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) | 178 | static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) |
184 | { | 179 | { |
180 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
185 | struct atmel_pcm_dma_params *prtd; | 181 | struct atmel_pcm_dma_params *prtd; |
186 | 182 | ||
187 | prtd = snd_dmaengine_pcm_get_data(substream); | 183 | prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
188 | 184 | ||
189 | ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); | 185 | ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); |
190 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); | 186 | ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); |
@@ -199,16 +195,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) | |||
199 | return 0; | 195 | return 0; |
200 | } | 196 | } |
201 | 197 | ||
202 | static int atmel_pcm_close(struct snd_pcm_substream *substream) | ||
203 | { | ||
204 | snd_dmaengine_pcm_close(substream); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static struct snd_pcm_ops atmel_pcm_ops = { | 198 | static struct snd_pcm_ops atmel_pcm_ops = { |
210 | .open = atmel_pcm_open, | 199 | .open = atmel_pcm_open, |
211 | .close = atmel_pcm_close, | 200 | .close = snd_dmaengine_pcm_close_release_chan, |
212 | .ioctl = snd_pcm_lib_ioctl, | 201 | .ioctl = snd_pcm_lib_ioctl, |
213 | .hw_params = atmel_pcm_hw_params, | 202 | .hw_params = atmel_pcm_hw_params, |
214 | .prepare = atmel_pcm_dma_prepare, | 203 | .prepare = atmel_pcm_dma_prepare, |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e13580d6c476..f3fdfa07fcb9 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -533,6 +533,49 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
533 | break; | 533 | break; |
534 | 534 | ||
535 | case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: | 535 | case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: |
536 | /* | ||
537 | * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. | ||
538 | * | ||
539 | * The SSC transmit clock is obtained from the BCLK signal on | ||
540 | * on the TK line, and the SSC receive clock is | ||
541 | * generated from the transmit clock. | ||
542 | * | ||
543 | * Data is transferred on first BCLK after LRC pulse rising | ||
544 | * edge.If stereo, the right channel data is contiguous with | ||
545 | * the left channel data. | ||
546 | */ | ||
547 | rcmr = SSC_BF(RCMR_PERIOD, 0) | ||
548 | | SSC_BF(RCMR_STTDLY, START_DELAY) | ||
549 | | SSC_BF(RCMR_START, SSC_START_RISING_RF) | ||
550 | | SSC_BF(RCMR_CKI, SSC_CKI_RISING) | ||
551 | | SSC_BF(RCMR_CKO, SSC_CKO_NONE) | ||
552 | | SSC_BF(RCMR_CKS, SSC_CKS_PIN); | ||
553 | |||
554 | rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | ||
555 | | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) | ||
556 | | SSC_BF(RFMR_FSLEN, 0) | ||
557 | | SSC_BF(RFMR_DATNB, (channels - 1)) | ||
558 | | SSC_BIT(RFMR_MSBF) | ||
559 | | SSC_BF(RFMR_LOOP, 0) | ||
560 | | SSC_BF(RFMR_DATLEN, (bits - 1)); | ||
561 | |||
562 | tcmr = SSC_BF(TCMR_PERIOD, 0) | ||
563 | | SSC_BF(TCMR_STTDLY, START_DELAY) | ||
564 | | SSC_BF(TCMR_START, SSC_START_RISING_RF) | ||
565 | | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) | ||
566 | | SSC_BF(TCMR_CKO, SSC_CKO_NONE) | ||
567 | | SSC_BF(TCMR_CKS, SSC_CKS_PIN); | ||
568 | |||
569 | tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) | ||
570 | | SSC_BF(TFMR_FSDEN, 0) | ||
571 | | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) | ||
572 | | SSC_BF(TFMR_FSLEN, 0) | ||
573 | | SSC_BF(TFMR_DATNB, (channels - 1)) | ||
574 | | SSC_BIT(TFMR_MSBF) | ||
575 | | SSC_BF(TFMR_DATDEF, 0) | ||
576 | | SSC_BF(TFMR_DATLEN, (bits - 1)); | ||
577 | break; | ||
578 | |||
536 | default: | 579 | default: |
537 | printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n", | 580 | printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n", |
538 | ssc_p->daifmt); | 581 | ssc_p->daifmt); |
@@ -707,13 +750,18 @@ static struct snd_soc_dai_driver atmel_ssc_dai = { | |||
707 | .ops = &atmel_ssc_dai_ops, | 750 | .ops = &atmel_ssc_dai_ops, |
708 | }; | 751 | }; |
709 | 752 | ||
753 | static const struct snd_soc_component_driver atmel_ssc_component = { | ||
754 | .name = "atmel-ssc", | ||
755 | }; | ||
756 | |||
710 | static int asoc_ssc_init(struct device *dev) | 757 | static int asoc_ssc_init(struct device *dev) |
711 | { | 758 | { |
712 | struct platform_device *pdev = to_platform_device(dev); | 759 | struct platform_device *pdev = to_platform_device(dev); |
713 | struct ssc_device *ssc = platform_get_drvdata(pdev); | 760 | struct ssc_device *ssc = platform_get_drvdata(pdev); |
714 | int ret; | 761 | int ret; |
715 | 762 | ||
716 | ret = snd_soc_register_dai(dev, &atmel_ssc_dai); | 763 | ret = snd_soc_register_component(dev, &atmel_ssc_component, |
764 | &atmel_ssc_dai, 1); | ||
717 | if (ret) { | 765 | if (ret) { |
718 | dev_err(dev, "Could not register DAI: %d\n", ret); | 766 | dev_err(dev, "Could not register DAI: %d\n", ret); |
719 | goto err; | 767 | goto err; |
@@ -732,7 +780,7 @@ static int asoc_ssc_init(struct device *dev) | |||
732 | return 0; | 780 | return 0; |
733 | 781 | ||
734 | err_unregister_dai: | 782 | err_unregister_dai: |
735 | snd_soc_unregister_dai(dev); | 783 | snd_soc_unregister_component(dev); |
736 | err: | 784 | err: |
737 | return ret; | 785 | return ret; |
738 | } | 786 | } |
@@ -747,7 +795,7 @@ static void asoc_ssc_exit(struct device *dev) | |||
747 | else | 795 | else |
748 | atmel_pcm_pdc_platform_unregister(dev); | 796 | atmel_pcm_pdc_platform_unregister(dev); |
749 | 797 | ||
750 | snd_soc_unregister_dai(dev); | 798 | snd_soc_unregister_component(dev); |
751 | } | 799 | } |
752 | 800 | ||
753 | /** | 801 | /** |
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index ea7d9d157022..44b8dcecf571 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c | |||
@@ -223,6 +223,10 @@ static struct snd_soc_dai_driver au1xac97c_dai_driver = { | |||
223 | .ops = &alchemy_ac97c_ops, | 223 | .ops = &alchemy_ac97c_ops, |
224 | }; | 224 | }; |
225 | 225 | ||
226 | static const struct snd_soc_component_driver au1xac97c_component = { | ||
227 | .name = "au1xac97c", | ||
228 | }; | ||
229 | |||
226 | static int au1xac97c_drvprobe(struct platform_device *pdev) | 230 | static int au1xac97c_drvprobe(struct platform_device *pdev) |
227 | { | 231 | { |
228 | int ret; | 232 | int ret; |
@@ -268,7 +272,8 @@ static int au1xac97c_drvprobe(struct platform_device *pdev) | |||
268 | 272 | ||
269 | platform_set_drvdata(pdev, ctx); | 273 | platform_set_drvdata(pdev, ctx); |
270 | 274 | ||
271 | ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver); | 275 | ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component, |
276 | &au1xac97c_dai_driver, 1); | ||
272 | if (ret) | 277 | if (ret) |
273 | return ret; | 278 | return ret; |
274 | 279 | ||
@@ -280,7 +285,7 @@ static int au1xac97c_drvremove(struct platform_device *pdev) | |||
280 | { | 285 | { |
281 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); | 286 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); |
282 | 287 | ||
283 | snd_soc_unregister_dai(&pdev->dev); | 288 | snd_soc_unregister_component(&pdev->dev); |
284 | 289 | ||
285 | WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ | 290 | WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ |
286 | 291 | ||
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 072448afc219..b3f37f6edbcb 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c | |||
@@ -225,6 +225,10 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = { | |||
225 | .ops = &au1xi2s_dai_ops, | 225 | .ops = &au1xi2s_dai_ops, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | static const struct snd_soc_component_driver au1xi2s_component = { | ||
229 | .name = "au1xi2s", | ||
230 | }; | ||
231 | |||
228 | static int au1xi2s_drvprobe(struct platform_device *pdev) | 232 | static int au1xi2s_drvprobe(struct platform_device *pdev) |
229 | { | 233 | { |
230 | struct resource *iores, *dmares; | 234 | struct resource *iores, *dmares; |
@@ -260,14 +264,15 @@ static int au1xi2s_drvprobe(struct platform_device *pdev) | |||
260 | 264 | ||
261 | platform_set_drvdata(pdev, ctx); | 265 | platform_set_drvdata(pdev, ctx); |
262 | 266 | ||
263 | return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); | 267 | return snd_soc_register_component(&pdev->dev, &au1xi2s_component, |
268 | &au1xi2s_dai_driver, 1); | ||
264 | } | 269 | } |
265 | 270 | ||
266 | static int au1xi2s_drvremove(struct platform_device *pdev) | 271 | static int au1xi2s_drvremove(struct platform_device *pdev) |
267 | { | 272 | { |
268 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); | 273 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); |
269 | 274 | ||
270 | snd_soc_unregister_dai(&pdev->dev); | 275 | snd_soc_unregister_component(&pdev->dev); |
271 | 276 | ||
272 | WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ | 277 | WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ |
273 | 278 | ||
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 6ba07e365967..8f1862aa7333 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c | |||
@@ -361,6 +361,10 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { | |||
361 | .ops = &au1xpsc_ac97_dai_ops, | 361 | .ops = &au1xpsc_ac97_dai_ops, |
362 | }; | 362 | }; |
363 | 363 | ||
364 | static const struct snd_soc_component_driver au1xpsc_ac97_component = { | ||
365 | .name = "au1xpsc-ac97", | ||
366 | }; | ||
367 | |||
364 | static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) | 368 | static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) |
365 | { | 369 | { |
366 | int ret; | 370 | int ret; |
@@ -419,7 +423,8 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) | |||
419 | 423 | ||
420 | platform_set_drvdata(pdev, wd); | 424 | platform_set_drvdata(pdev, wd); |
421 | 425 | ||
422 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 426 | ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, |
427 | &wd->dai_drv, 1); | ||
423 | if (ret) | 428 | if (ret) |
424 | return ret; | 429 | return ret; |
425 | 430 | ||
@@ -431,7 +436,7 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) | |||
431 | { | 436 | { |
432 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 437 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
433 | 438 | ||
434 | snd_soc_unregister_dai(&pdev->dev); | 439 | snd_soc_unregister_component(&pdev->dev); |
435 | 440 | ||
436 | /* disable PSC completely */ | 441 | /* disable PSC completely */ |
437 | au_writel(0, AC97_CFG(wd)); | 442 | au_writel(0, AC97_CFG(wd)); |
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 360b4e50d7c8..fe923a7bdc39 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c | |||
@@ -288,6 +288,10 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { | |||
288 | .ops = &au1xpsc_i2s_dai_ops, | 288 | .ops = &au1xpsc_i2s_dai_ops, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | static const struct snd_soc_component_driver au1xpsc_i2s_component = { | ||
292 | .name = "au1xpsc-i2s", | ||
293 | }; | ||
294 | |||
291 | static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) | 295 | static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) |
292 | { | 296 | { |
293 | struct resource *iores, *dmares; | 297 | struct resource *iores, *dmares; |
@@ -350,14 +354,15 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) | |||
350 | 354 | ||
351 | platform_set_drvdata(pdev, wd); | 355 | platform_set_drvdata(pdev, wd); |
352 | 356 | ||
353 | return snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 357 | return snd_soc_register_component(&pdev->dev, &au1xpsc_i2s_component, |
358 | &wd->dai_drv, 1); | ||
354 | } | 359 | } |
355 | 360 | ||
356 | static int au1xpsc_i2s_drvremove(struct platform_device *pdev) | 361 | static int au1xpsc_i2s_drvremove(struct platform_device *pdev) |
357 | { | 362 | { |
358 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 363 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
359 | 364 | ||
360 | snd_soc_unregister_dai(&pdev->dev); | 365 | snd_soc_unregister_component(&pdev->dev); |
361 | 366 | ||
362 | au_writel(0, I2S_CFG(wd)); | 367 | au_writel(0, I2S_CFG(wd)); |
363 | au_sync(); | 368 | au_sync(); |
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 8e41bcb020eb..490217325975 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c | |||
@@ -282,6 +282,10 @@ static struct snd_soc_dai_driver bfin_ac97_dai = { | |||
282 | .formats = SNDRV_PCM_FMTBIT_S16_LE, }, | 282 | .formats = SNDRV_PCM_FMTBIT_S16_LE, }, |
283 | }; | 283 | }; |
284 | 284 | ||
285 | static const struct snd_soc_component_driver bfin_ac97_component = { | ||
286 | .name = "bfin-ac97", | ||
287 | }; | ||
288 | |||
285 | static int asoc_bfin_ac97_probe(struct platform_device *pdev) | 289 | static int asoc_bfin_ac97_probe(struct platform_device *pdev) |
286 | { | 290 | { |
287 | struct sport_device *sport_handle; | 291 | struct sport_device *sport_handle; |
@@ -331,7 +335,8 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev) | |||
331 | goto sport_config_err; | 335 | goto sport_config_err; |
332 | } | 336 | } |
333 | 337 | ||
334 | ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai); | 338 | ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component, |
339 | &bfin_ac97_dai, 1); | ||
335 | if (ret) { | 340 | if (ret) { |
336 | pr_err("Failed to register DAI: %d\n", ret); | 341 | pr_err("Failed to register DAI: %d\n", ret); |
337 | goto sport_config_err; | 342 | goto sport_config_err; |
@@ -356,7 +361,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev) | |||
356 | { | 361 | { |
357 | struct sport_device *sport_handle = platform_get_drvdata(pdev); | 362 | struct sport_device *sport_handle = platform_get_drvdata(pdev); |
358 | 363 | ||
359 | snd_soc_unregister_dai(&pdev->dev); | 364 | snd_soc_unregister_component(&pdev->dev); |
360 | sport_done(sport_handle); | 365 | sport_done(sport_handle); |
361 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET | 366 | #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET |
362 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); | 367 | gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); |
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 168d88bccb41..dd0c2a4f83a3 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c | |||
@@ -245,6 +245,10 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = { | |||
245 | .ops = &bf5xx_i2s_dai_ops, | 245 | .ops = &bf5xx_i2s_dai_ops, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static const struct snd_soc_component_driver bf5xx_i2s_component = { | ||
249 | .name = "bf5xx-i2s", | ||
250 | }; | ||
251 | |||
248 | static int bf5xx_i2s_probe(struct platform_device *pdev) | 252 | static int bf5xx_i2s_probe(struct platform_device *pdev) |
249 | { | 253 | { |
250 | struct sport_device *sport_handle; | 254 | struct sport_device *sport_handle; |
@@ -257,7 +261,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev) | |||
257 | return -ENODEV; | 261 | return -ENODEV; |
258 | 262 | ||
259 | /* register with the ASoC layers */ | 263 | /* register with the ASoC layers */ |
260 | ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); | 264 | ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component, |
265 | &bf5xx_i2s_dai, 1); | ||
261 | if (ret) { | 266 | if (ret) { |
262 | pr_err("Failed to register DAI: %d\n", ret); | 267 | pr_err("Failed to register DAI: %d\n", ret); |
263 | sport_done(sport_handle); | 268 | sport_done(sport_handle); |
@@ -273,7 +278,7 @@ static int bf5xx_i2s_remove(struct platform_device *pdev) | |||
273 | 278 | ||
274 | pr_debug("%s enter\n", __func__); | 279 | pr_debug("%s enter\n", __func__); |
275 | 280 | ||
276 | snd_soc_unregister_dai(&pdev->dev); | 281 | snd_soc_unregister_component(&pdev->dev); |
277 | sport_done(sport_handle); | 282 | sport_done(sport_handle); |
278 | 283 | ||
279 | return 0; | 284 | return 0; |
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index c1e516ec53ad..69e9a3e935bd 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c | |||
@@ -249,6 +249,10 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = { | |||
249 | .ops = &bf5xx_tdm_dai_ops, | 249 | .ops = &bf5xx_tdm_dai_ops, |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static const struct snd_soc_component_driver bf5xx_tdm_component = { | ||
253 | .name = "bf5xx-tdm", | ||
254 | }; | ||
255 | |||
252 | static int bfin_tdm_probe(struct platform_device *pdev) | 256 | static int bfin_tdm_probe(struct platform_device *pdev) |
253 | { | 257 | { |
254 | struct sport_device *sport_handle; | 258 | struct sport_device *sport_handle; |
@@ -282,7 +286,8 @@ static int bfin_tdm_probe(struct platform_device *pdev) | |||
282 | goto sport_config_err; | 286 | goto sport_config_err; |
283 | } | 287 | } |
284 | 288 | ||
285 | ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai); | 289 | ret = snd_soc_register_component(&pdev->dev, &bf5xx_tdm_component, |
290 | &bf5xx_tdm_dai, 1); | ||
286 | if (ret) { | 291 | if (ret) { |
287 | pr_err("Failed to register DAI: %d\n", ret); | 292 | pr_err("Failed to register DAI: %d\n", ret); |
288 | goto sport_config_err; | 293 | goto sport_config_err; |
@@ -299,7 +304,7 @@ static int bfin_tdm_remove(struct platform_device *pdev) | |||
299 | { | 304 | { |
300 | struct sport_device *sport_handle = platform_get_drvdata(pdev); | 305 | struct sport_device *sport_handle = platform_get_drvdata(pdev); |
301 | 306 | ||
302 | snd_soc_unregister_dai(&pdev->dev); | 307 | snd_soc_unregister_component(&pdev->dev); |
303 | sport_done(sport_handle); | 308 | sport_done(sport_handle); |
304 | 309 | ||
305 | return 0; | 310 | return 0; |
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index 8f337972f438..c02405cc007d 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c | |||
@@ -186,6 +186,10 @@ static struct snd_soc_dai_driver bfin_i2s_dai = { | |||
186 | .ops = &bfin_i2s_dai_ops, | 186 | .ops = &bfin_i2s_dai_ops, |
187 | }; | 187 | }; |
188 | 188 | ||
189 | static const struct snd_soc_component_driver bfin_i2s_component = { | ||
190 | .name = "bfin-i2s", | ||
191 | }; | ||
192 | |||
189 | static int bfin_i2s_probe(struct platform_device *pdev) | 193 | static int bfin_i2s_probe(struct platform_device *pdev) |
190 | { | 194 | { |
191 | struct sport_device *sport; | 195 | struct sport_device *sport; |
@@ -197,7 +201,8 @@ static int bfin_i2s_probe(struct platform_device *pdev) | |||
197 | return -ENODEV; | 201 | return -ENODEV; |
198 | 202 | ||
199 | /* register with the ASoC layers */ | 203 | /* register with the ASoC layers */ |
200 | ret = snd_soc_register_dai(dev, &bfin_i2s_dai); | 204 | ret = snd_soc_register_component(dev, &bfin_i2s_component, |
205 | &bfin_i2s_dai, 1); | ||
201 | if (ret) { | 206 | if (ret) { |
202 | dev_err(dev, "Failed to register DAI: %d\n", ret); | 207 | dev_err(dev, "Failed to register DAI: %d\n", ret); |
203 | sport_delete(sport); | 208 | sport_delete(sport); |
@@ -212,7 +217,7 @@ static int bfin_i2s_remove(struct platform_device *pdev) | |||
212 | { | 217 | { |
213 | struct sport_device *sport = platform_get_drvdata(pdev); | 218 | struct sport_device *sport = platform_get_drvdata(pdev); |
214 | 219 | ||
215 | snd_soc_unregister_dai(&pdev->dev); | 220 | snd_soc_unregister_component(&pdev->dev); |
216 | sport_delete(sport); | 221 | sport_delete(sport); |
217 | 222 | ||
218 | return 0; | 223 | return 0; |
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 5db68cf7b281..c43fb214558a 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
28 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include "ep93xx-pcm.h" | ||
31 | 30 | ||
32 | static int edb93xx_hw_params(struct snd_pcm_substream *substream, | 31 | static int edb93xx_hw_params(struct snd_pcm_substream *substream, |
33 | struct snd_pcm_hw_params *params) | 32 | struct snd_pcm_hw_params *params) |
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 1738d28fb04f..7798fbd5e81d 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
24 | 24 | ||
25 | #include <linux/platform_data/dma-ep93xx.h> | 25 | #include <linux/platform_data/dma-ep93xx.h> |
26 | #include "ep93xx-pcm.h" | ||
27 | 26 | ||
28 | /* | 27 | /* |
29 | * Per channel (1-4) registers. | 28 | * Per channel (1-4) registers. |
@@ -101,14 +100,16 @@ struct ep93xx_ac97_info { | |||
101 | /* currently ALSA only supports a single AC97 device */ | 100 | /* currently ALSA only supports a single AC97 device */ |
102 | static struct ep93xx_ac97_info *ep93xx_ac97_info; | 101 | static struct ep93xx_ac97_info *ep93xx_ac97_info; |
103 | 102 | ||
104 | static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { | 103 | static struct ep93xx_dma_data ep93xx_ac97_pcm_out = { |
105 | .name = "ac97-pcm-out", | 104 | .name = "ac97-pcm-out", |
106 | .dma_port = EP93XX_DMA_AAC1, | 105 | .dma_port = EP93XX_DMA_AAC1, |
106 | .direction = DMA_MEM_TO_DEV, | ||
107 | }; | 107 | }; |
108 | 108 | ||
109 | static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { | 109 | static struct ep93xx_dma_data ep93xx_ac97_pcm_in = { |
110 | .name = "ac97-pcm-in", | 110 | .name = "ac97-pcm-in", |
111 | .dma_port = EP93XX_DMA_AAC1, | 111 | .dma_port = EP93XX_DMA_AAC1, |
112 | .direction = DMA_DEV_TO_MEM, | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, | 115 | static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, |
@@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, | |||
316 | static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, | 317 | static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, |
317 | struct snd_soc_dai *dai) | 318 | struct snd_soc_dai *dai) |
318 | { | 319 | { |
319 | struct ep93xx_pcm_dma_params *dma_data; | 320 | struct ep93xx_dma_data *dma_data; |
320 | 321 | ||
321 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 322 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
322 | dma_data = &ep93xx_ac97_pcm_out; | 323 | dma_data = &ep93xx_ac97_pcm_out; |
@@ -353,6 +354,10 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { | |||
353 | .ops = &ep93xx_ac97_dai_ops, | 354 | .ops = &ep93xx_ac97_dai_ops, |
354 | }; | 355 | }; |
355 | 356 | ||
357 | static const struct snd_soc_component_driver ep93xx_ac97_component = { | ||
358 | .name = "ep93xx-ac97", | ||
359 | }; | ||
360 | |||
356 | static int ep93xx_ac97_probe(struct platform_device *pdev) | 361 | static int ep93xx_ac97_probe(struct platform_device *pdev) |
357 | { | 362 | { |
358 | struct ep93xx_ac97_info *info; | 363 | struct ep93xx_ac97_info *info; |
@@ -390,7 +395,8 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) | |||
390 | ep93xx_ac97_info = info; | 395 | ep93xx_ac97_info = info; |
391 | platform_set_drvdata(pdev, info); | 396 | platform_set_drvdata(pdev, info); |
392 | 397 | ||
393 | ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai); | 398 | ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, |
399 | &ep93xx_ac97_dai, 1); | ||
394 | if (ret) | 400 | if (ret) |
395 | goto fail; | 401 | goto fail; |
396 | 402 | ||
@@ -407,7 +413,7 @@ static int ep93xx_ac97_remove(struct platform_device *pdev) | |||
407 | { | 413 | { |
408 | struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); | 414 | struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); |
409 | 415 | ||
410 | snd_soc_unregister_dai(&pdev->dev); | 416 | snd_soc_unregister_component(&pdev->dev); |
411 | 417 | ||
412 | /* disable the AC97 controller */ | 418 | /* disable the AC97 controller */ |
413 | ep93xx_ac97_write_reg(info, AC97GCR, 0); | 419 | ep93xx_ac97_write_reg(info, AC97GCR, 0); |
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 323ed69b7975..5c1102e9e159 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <mach/ep93xx-regs.h> | 30 | #include <mach/ep93xx-regs.h> |
31 | #include <linux/platform_data/dma-ep93xx.h> | 31 | #include <linux/platform_data/dma-ep93xx.h> |
32 | 32 | ||
33 | #include "ep93xx-pcm.h" | ||
34 | |||
35 | #define EP93XX_I2S_TXCLKCFG 0x00 | 33 | #define EP93XX_I2S_TXCLKCFG 0x00 |
36 | #define EP93XX_I2S_RXCLKCFG 0x04 | 34 | #define EP93XX_I2S_RXCLKCFG 0x04 |
37 | #define EP93XX_I2S_GLCTRL 0x0C | 35 | #define EP93XX_I2S_GLCTRL 0x0C |
@@ -62,18 +60,20 @@ struct ep93xx_i2s_info { | |||
62 | struct clk *mclk; | 60 | struct clk *mclk; |
63 | struct clk *sclk; | 61 | struct clk *sclk; |
64 | struct clk *lrclk; | 62 | struct clk *lrclk; |
65 | struct ep93xx_pcm_dma_params *dma_params; | 63 | struct ep93xx_dma_data *dma_data; |
66 | void __iomem *regs; | 64 | void __iomem *regs; |
67 | }; | 65 | }; |
68 | 66 | ||
69 | struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { | 67 | struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { |
70 | [SNDRV_PCM_STREAM_PLAYBACK] = { | 68 | [SNDRV_PCM_STREAM_PLAYBACK] = { |
71 | .name = "i2s-pcm-out", | 69 | .name = "i2s-pcm-out", |
72 | .dma_port = EP93XX_DMA_I2S1, | 70 | .port = EP93XX_DMA_I2S1, |
71 | .direction = DMA_MEM_TO_DEV, | ||
73 | }, | 72 | }, |
74 | [SNDRV_PCM_STREAM_CAPTURE] = { | 73 | [SNDRV_PCM_STREAM_CAPTURE] = { |
75 | .name = "i2s-pcm-in", | 74 | .name = "i2s-pcm-in", |
76 | .dma_port = EP93XX_DMA_I2S1, | 75 | .port = EP93XX_DMA_I2S1, |
76 | .direction = DMA_DEV_TO_MEM, | ||
77 | }, | 77 | }, |
78 | }; | 78 | }; |
79 | 79 | ||
@@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, | |||
147 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 147 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
148 | 148 | ||
149 | snd_soc_dai_set_dma_data(cpu_dai, substream, | 149 | snd_soc_dai_set_dma_data(cpu_dai, substream, |
150 | &info->dma_params[substream->stream]); | 150 | &info->dma_data[substream->stream]); |
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
@@ -366,6 +366,10 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = { | |||
366 | .ops = &ep93xx_i2s_dai_ops, | 366 | .ops = &ep93xx_i2s_dai_ops, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static const struct snd_soc_component_driver ep93xx_i2s_component = { | ||
370 | .name = "ep93xx-i2s", | ||
371 | }; | ||
372 | |||
369 | static int ep93xx_i2s_probe(struct platform_device *pdev) | 373 | static int ep93xx_i2s_probe(struct platform_device *pdev) |
370 | { | 374 | { |
371 | struct ep93xx_i2s_info *info; | 375 | struct ep93xx_i2s_info *info; |
@@ -403,9 +407,10 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) | |||
403 | } | 407 | } |
404 | 408 | ||
405 | dev_set_drvdata(&pdev->dev, info); | 409 | dev_set_drvdata(&pdev->dev, info); |
406 | info->dma_params = ep93xx_i2s_dma_params; | 410 | info->dma_data = ep93xx_i2s_dma_data; |
407 | 411 | ||
408 | err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); | 412 | err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, |
413 | &ep93xx_i2s_dai, 1); | ||
409 | if (err) | 414 | if (err) |
410 | goto fail_put_lrclk; | 415 | goto fail_put_lrclk; |
411 | 416 | ||
@@ -426,7 +431,7 @@ static int ep93xx_i2s_remove(struct platform_device *pdev) | |||
426 | { | 431 | { |
427 | struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); | 432 | struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); |
428 | 433 | ||
429 | snd_soc_unregister_dai(&pdev->dev); | 434 | snd_soc_unregister_component(&pdev->dev); |
430 | dev_set_drvdata(&pdev->dev, NULL); | 435 | dev_set_drvdata(&pdev->dev, NULL); |
431 | clk_put(info->lrclk); | 436 | clk_put(info->lrclk); |
432 | clk_put(info->sclk); | 437 | clk_put(info->sclk); |
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 72eb7a49e16a..488032690378 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c | |||
@@ -29,8 +29,6 @@ | |||
29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <mach/ep93xx-regs.h> | 30 | #include <mach/ep93xx-regs.h> |
31 | 31 | ||
32 | #include "ep93xx-pcm.h" | ||
33 | |||
34 | static const struct snd_pcm_hardware ep93xx_pcm_hardware = { | 32 | static const struct snd_pcm_hardware ep93xx_pcm_hardware = { |
35 | .info = (SNDRV_PCM_INFO_MMAP | | 33 | .info = (SNDRV_PCM_INFO_MMAP | |
36 | SNDRV_PCM_INFO_MMAP_VALID | | 34 | SNDRV_PCM_INFO_MMAP_VALID | |
@@ -68,40 +66,12 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) | |||
68 | static int ep93xx_pcm_open(struct snd_pcm_substream *substream) | 66 | static int ep93xx_pcm_open(struct snd_pcm_substream *substream) |
69 | { | 67 | { |
70 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 68 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
71 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
72 | struct ep93xx_pcm_dma_params *dma_params; | ||
73 | struct ep93xx_dma_data *dma_data; | ||
74 | int ret; | ||
75 | 69 | ||
76 | snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); | 70 | snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); |
77 | 71 | ||
78 | dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); | 72 | return snd_dmaengine_pcm_open_request_chan(substream, |
79 | if (!dma_data) | 73 | ep93xx_pcm_dma_filter, |
80 | return -ENOMEM; | 74 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); |
81 | |||
82 | dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); | ||
83 | dma_data->port = dma_params->dma_port; | ||
84 | dma_data->name = dma_params->name; | ||
85 | dma_data->direction = snd_pcm_substream_to_dma_direction(substream); | ||
86 | |||
87 | ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data); | ||
88 | if (ret) { | ||
89 | kfree(dma_data); | ||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | snd_dmaengine_pcm_set_data(substream, dma_data); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int ep93xx_pcm_close(struct snd_pcm_substream *substream) | ||
99 | { | ||
100 | struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); | ||
101 | |||
102 | snd_dmaengine_pcm_close(substream); | ||
103 | kfree(dma_data); | ||
104 | return 0; | ||
105 | } | 75 | } |
106 | 76 | ||
107 | static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, | 77 | static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, |
@@ -131,7 +101,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, | |||
131 | 101 | ||
132 | static struct snd_pcm_ops ep93xx_pcm_ops = { | 102 | static struct snd_pcm_ops ep93xx_pcm_ops = { |
133 | .open = ep93xx_pcm_open, | 103 | .open = ep93xx_pcm_open, |
134 | .close = ep93xx_pcm_close, | 104 | .close = snd_dmaengine_pcm_close_release_chan, |
135 | .ioctl = snd_pcm_lib_ioctl, | 105 | .ioctl = snd_pcm_lib_ioctl, |
136 | .hw_params = ep93xx_pcm_hw_params, | 106 | .hw_params = ep93xx_pcm_hw_params, |
137 | .hw_free = ep93xx_pcm_hw_free, | 107 | .hw_free = ep93xx_pcm_hw_free, |
diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h deleted file mode 100644 index 111e1121ecb8..000000000000 --- a/sound/soc/cirrus/ep93xx-pcm.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface | ||
3 | * | ||
4 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> | ||
5 | * Copyright (C) 2006 Applied Data Systems | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _EP93XX_SND_SOC_PCM_H | ||
13 | #define _EP93XX_SND_SOC_PCM_H | ||
14 | |||
15 | struct ep93xx_pcm_dma_params { | ||
16 | char *name; | ||
17 | int dma_port; | ||
18 | }; | ||
19 | |||
20 | #endif /* _EP93XX_SND_SOC_PCM_H */ | ||
diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index a397bb0d8179..4d094d00c34a 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | 23 | ||
24 | #include "ep93xx-pcm.h" | ||
25 | |||
26 | static struct snd_soc_dai_link simone_dai = { | 24 | static struct snd_soc_dai_link simone_dai = { |
27 | .name = "AC97", | 25 | .name = "AC97", |
28 | .stream_name = "AC97 HiFi", | 26 | .stream_name = "AC97 HiFi", |
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 9d77fe28dfcc..69041074f2c1 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | 22 | ||
23 | #include "../codecs/tlv320aic23.h" | 23 | #include "../codecs/tlv320aic23.h" |
24 | #include "ep93xx-pcm.h" | ||
25 | 24 | ||
26 | #define CODEC_CLOCK 5644800 | 25 | #define CODEC_CLOCK 5644800 |
27 | 26 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 45b72561c615..2f45f00e31b0 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS | |||
26 | select SND_SOC_AK4641 if I2C | 26 | select SND_SOC_AK4641 if I2C |
27 | select SND_SOC_AK4642 if I2C | 27 | select SND_SOC_AK4642 if I2C |
28 | select SND_SOC_AK4671 if I2C | 28 | select SND_SOC_AK4671 if I2C |
29 | select SND_SOC_AK5386 | ||
29 | select SND_SOC_ALC5623 if I2C | 30 | select SND_SOC_ALC5623 if I2C |
30 | select SND_SOC_ALC5632 if I2C | 31 | select SND_SOC_ALC5632 if I2C |
31 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 32 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
@@ -63,6 +64,7 @@ config SND_SOC_ALL_CODECS | |||
63 | select SND_SOC_STA32X if I2C | 64 | select SND_SOC_STA32X if I2C |
64 | select SND_SOC_STA529 if I2C | 65 | select SND_SOC_STA529 if I2C |
65 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS | 66 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS |
67 | select SND_SOC_TAS5086 if I2C | ||
66 | select SND_SOC_TLV320AIC23 if I2C | 68 | select SND_SOC_TLV320AIC23 if I2C |
67 | select SND_SOC_TLV320AIC26 if SPI_MASTER | 69 | select SND_SOC_TLV320AIC26 if SPI_MASTER |
68 | select SND_SOC_TLV320AIC32X4 if I2C | 70 | select SND_SOC_TLV320AIC32X4 if I2C |
@@ -203,6 +205,9 @@ config SND_SOC_AK4642 | |||
203 | config SND_SOC_AK4671 | 205 | config SND_SOC_AK4671 |
204 | tristate | 206 | tristate |
205 | 207 | ||
208 | config SND_SOC_AK5386 | ||
209 | tristate | ||
210 | |||
206 | config SND_SOC_ALC5623 | 211 | config SND_SOC_ALC5623 |
207 | tristate | 212 | tristate |
208 | config SND_SOC_ALC5632 | 213 | config SND_SOC_ALC5632 |
@@ -320,11 +325,14 @@ config SND_SOC_STA529 | |||
320 | config SND_SOC_STAC9766 | 325 | config SND_SOC_STAC9766 |
321 | tristate | 326 | tristate |
322 | 327 | ||
328 | config SND_SOC_TAS5086 | ||
329 | tristate | ||
330 | |||
323 | config SND_SOC_TLV320AIC23 | 331 | config SND_SOC_TLV320AIC23 |
324 | tristate | 332 | tristate |
325 | 333 | ||
326 | config SND_SOC_TLV320AIC26 | 334 | config SND_SOC_TLV320AIC26 |
327 | tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE | 335 | tristate |
328 | depends on SPI | 336 | depends on SPI |
329 | 337 | ||
330 | config SND_SOC_TLV320AIC32X4 | 338 | config SND_SOC_TLV320AIC32X4 |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6a3b3c3b8b41..b9e41c9a1f4c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -14,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o | |||
14 | snd-soc-ak4641-objs := ak4641.o | 14 | snd-soc-ak4641-objs := ak4641.o |
15 | snd-soc-ak4642-objs := ak4642.o | 15 | snd-soc-ak4642-objs := ak4642.o |
16 | snd-soc-ak4671-objs := ak4671.o | 16 | snd-soc-ak4671-objs := ak4671.o |
17 | snd-soc-ak5386-objs := ak5386.o | ||
17 | snd-soc-arizona-objs := arizona.o | 18 | snd-soc-arizona-objs := arizona.o |
18 | snd-soc-cq93vc-objs := cq93vc.o | 19 | snd-soc-cq93vc-objs := cq93vc.o |
19 | snd-soc-cs42l51-objs := cs42l51.o | 20 | snd-soc-cs42l51-objs := cs42l51.o |
@@ -55,6 +56,7 @@ snd-soc-ssm2602-objs := ssm2602.o | |||
55 | snd-soc-sta32x-objs := sta32x.o | 56 | snd-soc-sta32x-objs := sta32x.o |
56 | snd-soc-sta529-objs := sta529.o | 57 | snd-soc-sta529-objs := sta529.o |
57 | snd-soc-stac9766-objs := stac9766.o | 58 | snd-soc-stac9766-objs := stac9766.o |
59 | snd-soc-tas5086-objs := tas5086.o | ||
58 | snd-soc-tlv320aic23-objs := tlv320aic23.o | 60 | snd-soc-tlv320aic23-objs := tlv320aic23.o |
59 | snd-soc-tlv320aic26-objs := tlv320aic26.o | 61 | snd-soc-tlv320aic26-objs := tlv320aic26.o |
60 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | 62 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o |
@@ -137,6 +139,7 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o | |||
137 | obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o | 139 | obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o |
138 | obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o | 140 | obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o |
139 | obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o | 141 | obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o |
142 | obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o | ||
140 | obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o | 143 | obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o |
141 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o | 144 | obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o |
142 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o | 145 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o |
@@ -177,6 +180,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | |||
177 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o | 180 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o |
178 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o | 181 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o |
179 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o | 182 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o |
183 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o | ||
180 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o | 184 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o |
181 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o | 185 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o |
182 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | 186 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 068b3ae56a17..1aa10ddf3a61 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -133,6 +133,8 @@ struct adau1373 { | |||
133 | #define ADAU1373_DAI_FORMAT_DSP 0x3 | 133 | #define ADAU1373_DAI_FORMAT_DSP 0x3 |
134 | 134 | ||
135 | #define ADAU1373_BCLKDIV_SOURCE BIT(5) | 135 | #define ADAU1373_BCLKDIV_SOURCE BIT(5) |
136 | #define ADAU1373_BCLKDIV_SR_MASK (0x07 << 2) | ||
137 | #define ADAU1373_BCLKDIV_BCLK_MASK 0x03 | ||
136 | #define ADAU1373_BCLKDIV_32 0x03 | 138 | #define ADAU1373_BCLKDIV_32 0x03 |
137 | #define ADAU1373_BCLKDIV_64 0x02 | 139 | #define ADAU1373_BCLKDIV_64 0x02 |
138 | #define ADAU1373_BCLKDIV_128 0x01 | 140 | #define ADAU1373_BCLKDIV_128 0x01 |
@@ -937,7 +939,8 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream, | |||
937 | adau1373_dai->enable_src = (div != 0); | 939 | adau1373_dai->enable_src = (div != 0); |
938 | 940 | ||
939 | snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), | 941 | snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), |
940 | ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64); | 942 | ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, |
943 | (div << 2) | ADAU1373_BCLKDIV_64); | ||
941 | 944 | ||
942 | switch (params_format(params)) { | 945 | switch (params_format(params)) { |
943 | case SNDRV_PCM_FORMAT_S16_LE: | 946 | case SNDRV_PCM_FORMAT_S16_LE: |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 6f6c335a5baa..c7cfdf957e4d 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -55,6 +55,7 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
55 | unsigned int format) | 55 | unsigned int format) |
56 | { | 56 | { |
57 | struct snd_soc_codec *codec = codec_dai->codec; | 57 | struct snd_soc_codec *codec = codec_dai->codec; |
58 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | ||
58 | int val = 0; | 59 | int val = 0; |
59 | int ret; | 60 | int ret; |
60 | 61 | ||
@@ -77,9 +78,9 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
77 | if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) | 78 | if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) |
78 | return -EINVAL; | 79 | return -EINVAL; |
79 | 80 | ||
80 | ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, | 81 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
81 | AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, | 82 | AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, |
82 | val); | 83 | val); |
83 | if (ret < 0) | 84 | if (ret < 0) |
84 | return ret; | 85 | return ret; |
85 | 86 | ||
@@ -91,11 +92,12 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
91 | struct snd_soc_dai *dai) | 92 | struct snd_soc_dai *dai) |
92 | { | 93 | { |
93 | struct snd_soc_codec *codec = dai->codec; | 94 | struct snd_soc_codec *codec = dai->codec; |
94 | int val = 0; | 95 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
96 | int ret, val = 0; | ||
95 | 97 | ||
96 | /* set the IEC958 bits: consumer mode, no copyright bit */ | 98 | /* set the IEC958 bits: consumer mode, no copyright bit */ |
97 | val |= IEC958_AES0_CON_NOT_COPYRIGHT; | 99 | val |= IEC958_AES0_CON_NOT_COPYRIGHT; |
98 | snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val); | 100 | regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(0), val); |
99 | 101 | ||
100 | val = 0; | 102 | val = 0; |
101 | 103 | ||
@@ -132,11 +134,33 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
132 | return -EINVAL; | 134 | return -EINVAL; |
133 | } | 135 | } |
134 | 136 | ||
135 | return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val); | 137 | ret = regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val); |
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | /* enable transmitter */ | ||
142 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, | ||
143 | AK4104_TX_TXE, AK4104_TX_TXE); | ||
144 | if (ret < 0) | ||
145 | return ret; | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int ak4104_hw_free(struct snd_pcm_substream *substream, | ||
151 | struct snd_soc_dai *dai) | ||
152 | { | ||
153 | struct snd_soc_codec *codec = dai->codec; | ||
154 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | ||
155 | |||
156 | /* disable transmitter */ | ||
157 | return regmap_update_bits(ak4104->regmap, AK4104_REG_TX, | ||
158 | AK4104_TX_TXE, 0); | ||
136 | } | 159 | } |
137 | 160 | ||
138 | static const struct snd_soc_dai_ops ak4101_dai_ops = { | 161 | static const struct snd_soc_dai_ops ak4101_dai_ops = { |
139 | .hw_params = ak4104_hw_params, | 162 | .hw_params = ak4104_hw_params, |
163 | .hw_free = ak4104_hw_free, | ||
140 | .set_fmt = ak4104_set_dai_fmt, | 164 | .set_fmt = ak4104_set_dai_fmt, |
141 | }; | 165 | }; |
142 | 166 | ||
@@ -160,20 +184,17 @@ static int ak4104_probe(struct snd_soc_codec *codec) | |||
160 | int ret; | 184 | int ret; |
161 | 185 | ||
162 | codec->control_data = ak4104->regmap; | 186 | codec->control_data = ak4104->regmap; |
163 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
164 | if (ret != 0) | ||
165 | return ret; | ||
166 | 187 | ||
167 | /* set power-up and non-reset bits */ | 188 | /* set power-up and non-reset bits */ |
168 | ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, | 189 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
169 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, | 190 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, |
170 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); | 191 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); |
171 | if (ret < 0) | 192 | if (ret < 0) |
172 | return ret; | 193 | return ret; |
173 | 194 | ||
174 | /* enable transmitter */ | 195 | /* enable transmitter */ |
175 | ret = snd_soc_update_bits(codec, AK4104_REG_TX, | 196 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, |
176 | AK4104_TX_TXE, AK4104_TX_TXE); | 197 | AK4104_TX_TXE, AK4104_TX_TXE); |
177 | if (ret < 0) | 198 | if (ret < 0) |
178 | return ret; | 199 | return ret; |
179 | 200 | ||
@@ -182,8 +203,10 @@ static int ak4104_probe(struct snd_soc_codec *codec) | |||
182 | 203 | ||
183 | static int ak4104_remove(struct snd_soc_codec *codec) | 204 | static int ak4104_remove(struct snd_soc_codec *codec) |
184 | { | 205 | { |
185 | snd_soc_update_bits(codec, AK4104_REG_CONTROL1, | 206 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
186 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); | 207 | |
208 | regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, | ||
209 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); | ||
187 | 210 | ||
188 | return 0; | 211 | return 0; |
189 | } | 212 | } |
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c new file mode 100644 index 000000000000..1f303983ae02 --- /dev/null +++ b/sound/soc/codecs/ak5386.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * ALSA SoC driver for | ||
3 | * Asahi Kasei AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC | ||
4 | * | ||
5 | * (c) 2013 Daniel Mack <zonque@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_gpio.h> | ||
16 | #include <linux/of_device.h> | ||
17 | #include <sound/soc.h> | ||
18 | #include <sound/pcm.h> | ||
19 | #include <sound/initval.h> | ||
20 | |||
21 | struct ak5386_priv { | ||
22 | int reset_gpio; | ||
23 | }; | ||
24 | |||
25 | static struct snd_soc_codec_driver soc_codec_ak5386; | ||
26 | |||
27 | static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
28 | unsigned int format) | ||
29 | { | ||
30 | struct snd_soc_codec *codec = codec_dai->codec; | ||
31 | |||
32 | format &= SND_SOC_DAIFMT_FORMAT_MASK; | ||
33 | if (format != SND_SOC_DAIFMT_LEFT_J && | ||
34 | format != SND_SOC_DAIFMT_I2S) { | ||
35 | dev_err(codec->dev, "Invalid DAI format\n"); | ||
36 | return -EINVAL; | ||
37 | } | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int ak5386_hw_params(struct snd_pcm_substream *substream, | ||
43 | struct snd_pcm_hw_params *params, | ||
44 | struct snd_soc_dai *dai) | ||
45 | { | ||
46 | struct snd_soc_codec *codec = dai->codec; | ||
47 | struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
48 | |||
49 | /* | ||
50 | * From the datasheet: | ||
51 | * | ||
52 | * All external clocks (MCLK, SCLK and LRCK) must be present unless | ||
53 | * PDN pin = “L”. If these clocks are not provided, the AK5386 may | ||
54 | * draw excess current due to its use of internal dynamically | ||
55 | * refreshed logic. If the external clocks are not present, place | ||
56 | * the AK5386 in power-down mode (PDN pin = “L”). | ||
57 | */ | ||
58 | |||
59 | if (gpio_is_valid(priv->reset_gpio)) | ||
60 | gpio_set_value(priv->reset_gpio, 1); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int ak5386_hw_free(struct snd_pcm_substream *substream, | ||
66 | struct snd_soc_dai *dai) | ||
67 | { | ||
68 | struct snd_soc_codec *codec = dai->codec; | ||
69 | struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
70 | |||
71 | if (gpio_is_valid(priv->reset_gpio)) | ||
72 | gpio_set_value(priv->reset_gpio, 0); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static const struct snd_soc_dai_ops ak5386_dai_ops = { | ||
78 | .set_fmt = ak5386_set_dai_fmt, | ||
79 | .hw_params = ak5386_hw_params, | ||
80 | .hw_free = ak5386_hw_free, | ||
81 | }; | ||
82 | |||
83 | static struct snd_soc_dai_driver ak5386_dai = { | ||
84 | .name = "ak5386-hifi", | ||
85 | .capture = { | ||
86 | .stream_name = "Capture", | ||
87 | .channels_min = 1, | ||
88 | .channels_max = 2, | ||
89 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
90 | .formats = SNDRV_PCM_FMTBIT_S8 | | ||
91 | SNDRV_PCM_FMTBIT_S16_LE | | ||
92 | SNDRV_PCM_FMTBIT_S24_LE | | ||
93 | SNDRV_PCM_FMTBIT_S24_3LE, | ||
94 | }, | ||
95 | .ops = &ak5386_dai_ops, | ||
96 | }; | ||
97 | |||
98 | #ifdef CONFIG_OF | ||
99 | static const struct of_device_id ak5386_dt_ids[] = { | ||
100 | { .compatible = "asahi-kasei,ak5386", }, | ||
101 | { } | ||
102 | }; | ||
103 | MODULE_DEVICE_TABLE(of, ak5386_dt_ids); | ||
104 | #endif | ||
105 | |||
106 | static int ak5386_probe(struct platform_device *pdev) | ||
107 | { | ||
108 | struct device *dev = &pdev->dev; | ||
109 | struct ak5386_priv *priv; | ||
110 | |||
111 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
112 | if (!priv) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | priv->reset_gpio = -EINVAL; | ||
116 | dev_set_drvdata(dev, priv); | ||
117 | |||
118 | if (of_match_device(of_match_ptr(ak5386_dt_ids), dev)) | ||
119 | priv->reset_gpio = of_get_named_gpio(dev->of_node, | ||
120 | "reset-gpio", 0); | ||
121 | |||
122 | if (gpio_is_valid(priv->reset_gpio)) | ||
123 | if (devm_gpio_request_one(dev, priv->reset_gpio, | ||
124 | GPIOF_OUT_INIT_LOW, | ||
125 | "AK5386 Reset")) | ||
126 | priv->reset_gpio = -EINVAL; | ||
127 | |||
128 | return snd_soc_register_codec(dev, &soc_codec_ak5386, | ||
129 | &ak5386_dai, 1); | ||
130 | } | ||
131 | |||
132 | static int ak5386_remove(struct platform_device *pdev) | ||
133 | { | ||
134 | snd_soc_unregister_codec(&pdev->dev); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static struct platform_driver ak5386_driver = { | ||
139 | .probe = ak5386_probe, | ||
140 | .remove = ak5386_remove, | ||
141 | .driver = { | ||
142 | .name = "ak5386", | ||
143 | .owner = THIS_MODULE, | ||
144 | .of_match_table = of_match_ptr(ak5386_dt_ids), | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | module_platform_driver(ak5386_driver); | ||
149 | |||
150 | MODULE_DESCRIPTION("ASoC driver for AK5386 ADC"); | ||
151 | MODULE_AUTHOR("Daniel Mack <zonque@gmail.com>"); | ||
152 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e7d34711412c..389f23253831 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | ||
13 | #include <linux/gcd.h> | 14 | #include <linux/gcd.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
@@ -65,6 +66,163 @@ | |||
65 | #define arizona_aif_dbg(_dai, fmt, ...) \ | 66 | #define arizona_aif_dbg(_dai, fmt, ...) \ |
66 | dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) | 67 | dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) |
67 | 68 | ||
69 | static int arizona_spk_ev(struct snd_soc_dapm_widget *w, | ||
70 | struct snd_kcontrol *kcontrol, | ||
71 | int event) | ||
72 | { | ||
73 | struct snd_soc_codec *codec = w->codec; | ||
74 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | ||
75 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
76 | bool manual_ena = false; | ||
77 | int val; | ||
78 | |||
79 | switch (arizona->type) { | ||
80 | case WM5102: | ||
81 | switch (arizona->rev) { | ||
82 | case 0: | ||
83 | break; | ||
84 | default: | ||
85 | manual_ena = true; | ||
86 | break; | ||
87 | } | ||
88 | default: | ||
89 | break; | ||
90 | } | ||
91 | |||
92 | switch (event) { | ||
93 | case SND_SOC_DAPM_PRE_PMU: | ||
94 | if (!priv->spk_ena && manual_ena) { | ||
95 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
96 | priv->spk_ena_pending = true; | ||
97 | } | ||
98 | break; | ||
99 | case SND_SOC_DAPM_POST_PMU: | ||
100 | val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); | ||
101 | if (val & ARIZONA_SPK_SHUTDOWN_STS) { | ||
102 | dev_crit(arizona->dev, | ||
103 | "Speaker not enabled due to temperature\n"); | ||
104 | return -EBUSY; | ||
105 | } | ||
106 | |||
107 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | ||
108 | 1 << w->shift, 1 << w->shift); | ||
109 | |||
110 | if (priv->spk_ena_pending) { | ||
111 | msleep(75); | ||
112 | snd_soc_write(codec, 0x4f5, 0xda); | ||
113 | priv->spk_ena_pending = false; | ||
114 | priv->spk_ena++; | ||
115 | } | ||
116 | break; | ||
117 | case SND_SOC_DAPM_PRE_PMD: | ||
118 | if (manual_ena) { | ||
119 | priv->spk_ena--; | ||
120 | if (!priv->spk_ena) | ||
121 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
122 | } | ||
123 | |||
124 | snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, | ||
125 | 1 << w->shift, 0); | ||
126 | break; | ||
127 | case SND_SOC_DAPM_POST_PMD: | ||
128 | if (manual_ena) { | ||
129 | if (!priv->spk_ena) | ||
130 | snd_soc_write(codec, 0x4f5, 0x0da); | ||
131 | } | ||
132 | break; | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static irqreturn_t arizona_thermal_warn(int irq, void *data) | ||
139 | { | ||
140 | struct arizona *arizona = data; | ||
141 | unsigned int val; | ||
142 | int ret; | ||
143 | |||
144 | ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, | ||
145 | &val); | ||
146 | if (ret != 0) { | ||
147 | dev_err(arizona->dev, "Failed to read thermal status: %d\n", | ||
148 | ret); | ||
149 | } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) { | ||
150 | dev_crit(arizona->dev, "Thermal warning\n"); | ||
151 | } | ||
152 | |||
153 | return IRQ_HANDLED; | ||
154 | } | ||
155 | |||
156 | static irqreturn_t arizona_thermal_shutdown(int irq, void *data) | ||
157 | { | ||
158 | struct arizona *arizona = data; | ||
159 | unsigned int val; | ||
160 | int ret; | ||
161 | |||
162 | ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, | ||
163 | &val); | ||
164 | if (ret != 0) { | ||
165 | dev_err(arizona->dev, "Failed to read thermal status: %d\n", | ||
166 | ret); | ||
167 | } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { | ||
168 | dev_crit(arizona->dev, "Thermal shutdown\n"); | ||
169 | ret = regmap_update_bits(arizona->regmap, | ||
170 | ARIZONA_OUTPUT_ENABLES_1, | ||
171 | ARIZONA_OUT4L_ENA | | ||
172 | ARIZONA_OUT4R_ENA, 0); | ||
173 | if (ret != 0) | ||
174 | dev_crit(arizona->dev, | ||
175 | "Failed to disable speaker outputs: %d\n", | ||
176 | ret); | ||
177 | } | ||
178 | |||
179 | return IRQ_HANDLED; | ||
180 | } | ||
181 | |||
182 | static const struct snd_soc_dapm_widget arizona_spkl = | ||
183 | SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, | ||
184 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | ||
185 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | ||
186 | |||
187 | static const struct snd_soc_dapm_widget arizona_spkr = | ||
188 | SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, | ||
189 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, | ||
190 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); | ||
191 | |||
192 | int arizona_init_spk(struct snd_soc_codec *codec) | ||
193 | { | ||
194 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
195 | struct arizona *arizona = priv->arizona; | ||
196 | int ret; | ||
197 | |||
198 | ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); | ||
199 | if (ret != 0) | ||
200 | return ret; | ||
201 | |||
202 | ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1); | ||
203 | if (ret != 0) | ||
204 | return ret; | ||
205 | |||
206 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN, | ||
207 | "Thermal warning", arizona_thermal_warn, | ||
208 | arizona); | ||
209 | if (ret != 0) | ||
210 | dev_err(arizona->dev, | ||
211 | "Failed to get thermal warning IRQ: %d\n", | ||
212 | ret); | ||
213 | |||
214 | ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN, | ||
215 | "Thermal shutdown", arizona_thermal_shutdown, | ||
216 | arizona); | ||
217 | if (ret != 0) | ||
218 | dev_err(arizona->dev, | ||
219 | "Failed to get thermal shutdown IRQ: %d\n", | ||
220 | ret); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(arizona_init_spk); | ||
225 | |||
68 | const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { | 226 | const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { |
69 | "None", | 227 | "None", |
70 | "Tone Generator 1", | 228 | "Tone Generator 1", |
@@ -274,6 +432,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); | |||
274 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); | 432 | const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); |
275 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); | 433 | EXPORT_SYMBOL_GPL(arizona_mixer_tlv); |
276 | 434 | ||
435 | const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { | ||
436 | "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", | ||
437 | }; | ||
438 | EXPORT_SYMBOL_GPL(arizona_rate_text); | ||
439 | |||
440 | const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { | ||
441 | 0, 1, 2, 8, | ||
442 | }; | ||
443 | EXPORT_SYMBOL_GPL(arizona_rate_val); | ||
444 | |||
445 | |||
446 | const struct soc_enum arizona_isrc_fsl[] = { | ||
447 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, | ||
448 | ARIZONA_ISRC1_FSL_SHIFT, 0xf, | ||
449 | ARIZONA_RATE_ENUM_SIZE, | ||
450 | arizona_rate_text, arizona_rate_val), | ||
451 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2, | ||
452 | ARIZONA_ISRC2_FSL_SHIFT, 0xf, | ||
453 | ARIZONA_RATE_ENUM_SIZE, | ||
454 | arizona_rate_text, arizona_rate_val), | ||
455 | SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2, | ||
456 | ARIZONA_ISRC3_FSL_SHIFT, 0xf, | ||
457 | ARIZONA_RATE_ENUM_SIZE, | ||
458 | arizona_rate_text, arizona_rate_val), | ||
459 | }; | ||
460 | EXPORT_SYMBOL_GPL(arizona_isrc_fsl); | ||
461 | |||
277 | static const char *arizona_vol_ramp_text[] = { | 462 | static const char *arizona_vol_ramp_text[] = { |
278 | "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", | 463 | "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", |
279 | "15ms/6dB", "30ms/6dB", | 464 | "15ms/6dB", "30ms/6dB", |
@@ -332,9 +517,27 @@ const struct soc_enum arizona_ng_hold = | |||
332 | 4, arizona_ng_hold_text); | 517 | 4, arizona_ng_hold_text); |
333 | EXPORT_SYMBOL_GPL(arizona_ng_hold); | 518 | EXPORT_SYMBOL_GPL(arizona_ng_hold); |
334 | 519 | ||
520 | static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) | ||
521 | { | ||
522 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
523 | unsigned int val; | ||
524 | int i; | ||
525 | |||
526 | if (ena) | ||
527 | val = ARIZONA_IN_VU; | ||
528 | else | ||
529 | val = 0; | ||
530 | |||
531 | for (i = 0; i < priv->num_inputs; i++) | ||
532 | snd_soc_update_bits(codec, | ||
533 | ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4), | ||
534 | ARIZONA_IN_VU, val); | ||
535 | } | ||
536 | |||
335 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | 537 | int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, |
336 | int event) | 538 | int event) |
337 | { | 539 | { |
540 | struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); | ||
338 | unsigned int reg; | 541 | unsigned int reg; |
339 | 542 | ||
340 | if (w->shift % 2) | 543 | if (w->shift % 2) |
@@ -343,13 +546,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, | |||
343 | reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); | 546 | reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); |
344 | 547 | ||
345 | switch (event) { | 548 | switch (event) { |
549 | case SND_SOC_DAPM_PRE_PMU: | ||
550 | priv->in_pending++; | ||
551 | break; | ||
346 | case SND_SOC_DAPM_POST_PMU: | 552 | case SND_SOC_DAPM_POST_PMU: |
347 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); | 553 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); |
554 | |||
555 | /* If this is the last input pending then allow VU */ | ||
556 | priv->in_pending--; | ||
557 | if (priv->in_pending == 0) { | ||
558 | msleep(1); | ||
559 | arizona_in_set_vu(w->codec, 1); | ||
560 | } | ||
348 | break; | 561 | break; |
349 | case SND_SOC_DAPM_PRE_PMD: | 562 | case SND_SOC_DAPM_PRE_PMD: |
350 | snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, | 563 | snd_soc_update_bits(w->codec, reg, |
351 | ARIZONA_IN1L_MUTE); | 564 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, |
565 | ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); | ||
352 | break; | 566 | break; |
567 | case SND_SOC_DAPM_POST_PMD: | ||
568 | /* Disable volume updates if no inputs are enabled */ | ||
569 | reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); | ||
570 | if (reg == 0) | ||
571 | arizona_in_set_vu(w->codec, 0); | ||
353 | } | 572 | } |
354 | 573 | ||
355 | return 0; | 574 | return 0; |
@@ -360,6 +579,24 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, | |||
360 | struct snd_kcontrol *kcontrol, | 579 | struct snd_kcontrol *kcontrol, |
361 | int event) | 580 | int event) |
362 | { | 581 | { |
582 | switch (event) { | ||
583 | case SND_SOC_DAPM_POST_PMU: | ||
584 | switch (w->shift) { | ||
585 | case ARIZONA_OUT1L_ENA_SHIFT: | ||
586 | case ARIZONA_OUT1R_ENA_SHIFT: | ||
587 | case ARIZONA_OUT2L_ENA_SHIFT: | ||
588 | case ARIZONA_OUT2R_ENA_SHIFT: | ||
589 | case ARIZONA_OUT3L_ENA_SHIFT: | ||
590 | case ARIZONA_OUT3R_ENA_SHIFT: | ||
591 | msleep(17); | ||
592 | break; | ||
593 | |||
594 | default: | ||
595 | break; | ||
596 | } | ||
597 | break; | ||
598 | } | ||
599 | |||
363 | return 0; | 600 | return 0; |
364 | } | 601 | } |
365 | EXPORT_SYMBOL_GPL(arizona_out_ev); | 602 | EXPORT_SYMBOL_GPL(arizona_out_ev); |
@@ -502,27 +739,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, | |||
502 | break; | 739 | break; |
503 | case 11289600: | 740 | case 11289600: |
504 | case 12288000: | 741 | case 12288000: |
505 | val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; | 742 | val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
506 | break; | 743 | break; |
507 | case 22579200: | 744 | case 22579200: |
508 | case 24576000: | 745 | case 24576000: |
509 | val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; | 746 | val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
510 | break; | 747 | break; |
511 | case 45158400: | 748 | case 45158400: |
512 | case 49152000: | 749 | case 49152000: |
513 | val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; | 750 | val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
514 | break; | 751 | break; |
515 | case 67737600: | 752 | case 67737600: |
516 | case 73728000: | 753 | case 73728000: |
517 | val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; | 754 | val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
518 | break; | 755 | break; |
519 | case 90316800: | 756 | case 90316800: |
520 | case 98304000: | 757 | case 98304000: |
521 | val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; | 758 | val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
522 | break; | 759 | break; |
523 | case 135475200: | 760 | case 135475200: |
524 | case 147456000: | 761 | case 147456000: |
525 | val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; | 762 | val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; |
526 | break; | 763 | break; |
527 | case 0: | 764 | case 0: |
528 | dev_dbg(arizona->dev, "%s cleared\n", name); | 765 | dev_dbg(arizona->dev, "%s cleared\n", name); |
@@ -816,7 +1053,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
816 | struct arizona *arizona = priv->arizona; | 1053 | struct arizona *arizona = priv->arizona; |
817 | int base = dai->driver->base; | 1054 | int base = dai->driver->base; |
818 | const int *rates; | 1055 | const int *rates; |
819 | int i, ret; | 1056 | int i, ret, val; |
820 | int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; | 1057 | int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; |
821 | int bclk, lrclk, wl, frame, bclk_target; | 1058 | int bclk, lrclk, wl, frame, bclk_target; |
822 | 1059 | ||
@@ -832,6 +1069,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, | |||
832 | bclk_target *= chan_limit; | 1069 | bclk_target *= chan_limit; |
833 | } | 1070 | } |
834 | 1071 | ||
1072 | /* Force stereo for I2S mode */ | ||
1073 | val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); | ||
1074 | if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) { | ||
1075 | arizona_aif_dbg(dai, "Forcing stereo mode\n"); | ||
1076 | bclk_target *= 2; | ||
1077 | } | ||
1078 | |||
835 | for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { | 1079 | for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { |
836 | if (rates[i] >= bclk_target && | 1080 | if (rates[i] >= bclk_target && |
837 | rates[i] % params_rate(params) == 0) { | 1081 | rates[i] % params_rate(params) == 0) { |
@@ -988,6 +1232,16 @@ static struct { | |||
988 | { 1000000, 13500000, 0, 1 }, | 1232 | { 1000000, 13500000, 0, 1 }, |
989 | }; | 1233 | }; |
990 | 1234 | ||
1235 | static struct { | ||
1236 | unsigned int min; | ||
1237 | unsigned int max; | ||
1238 | u16 gain; | ||
1239 | } fll_gains[] = { | ||
1240 | { 0, 256000, 0 }, | ||
1241 | { 256000, 1000000, 2 }, | ||
1242 | { 1000000, 13500000, 4 }, | ||
1243 | }; | ||
1244 | |||
991 | struct arizona_fll_cfg { | 1245 | struct arizona_fll_cfg { |
992 | int n; | 1246 | int n; |
993 | int theta; | 1247 | int theta; |
@@ -995,6 +1249,7 @@ struct arizona_fll_cfg { | |||
995 | int refdiv; | 1249 | int refdiv; |
996 | int outdiv; | 1250 | int outdiv; |
997 | int fratio; | 1251 | int fratio; |
1252 | int gain; | ||
998 | }; | 1253 | }; |
999 | 1254 | ||
1000 | static int arizona_calc_fll(struct arizona_fll *fll, | 1255 | static int arizona_calc_fll(struct arizona_fll *fll, |
@@ -1054,6 +1309,18 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
1054 | return -EINVAL; | 1309 | return -EINVAL; |
1055 | } | 1310 | } |
1056 | 1311 | ||
1312 | for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { | ||
1313 | if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { | ||
1314 | cfg->gain = fll_gains[i].gain; | ||
1315 | break; | ||
1316 | } | ||
1317 | } | ||
1318 | if (i == ARRAY_SIZE(fll_gains)) { | ||
1319 | arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", | ||
1320 | Fref); | ||
1321 | return -EINVAL; | ||
1322 | } | ||
1323 | |||
1057 | cfg->n = target / (ratio * Fref); | 1324 | cfg->n = target / (ratio * Fref); |
1058 | 1325 | ||
1059 | if (target % (ratio * Fref)) { | 1326 | if (target % (ratio * Fref)) { |
@@ -1081,13 +1348,15 @@ static int arizona_calc_fll(struct arizona_fll *fll, | |||
1081 | cfg->n, cfg->theta, cfg->lambda); | 1348 | cfg->n, cfg->theta, cfg->lambda); |
1082 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", | 1349 | arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", |
1083 | cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); | 1350 | cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); |
1351 | arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain); | ||
1084 | 1352 | ||
1085 | return 0; | 1353 | return 0; |
1086 | 1354 | ||
1087 | } | 1355 | } |
1088 | 1356 | ||
1089 | static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | 1357 | static void arizona_apply_fll(struct arizona *arizona, unsigned int base, |
1090 | struct arizona_fll_cfg *cfg, int source) | 1358 | struct arizona_fll_cfg *cfg, int source, |
1359 | bool sync) | ||
1091 | { | 1360 | { |
1092 | regmap_update_bits(arizona->regmap, base + 3, | 1361 | regmap_update_bits(arizona->regmap, base + 3, |
1093 | ARIZONA_FLL1_THETA_MASK, cfg->theta); | 1362 | ARIZONA_FLL1_THETA_MASK, cfg->theta); |
@@ -1102,87 +1371,84 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, | |||
1102 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | | 1371 | cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | |
1103 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); | 1372 | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); |
1104 | 1373 | ||
1374 | if (sync) | ||
1375 | regmap_update_bits(arizona->regmap, base + 0x7, | ||
1376 | ARIZONA_FLL1_GAIN_MASK, | ||
1377 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
1378 | else | ||
1379 | regmap_update_bits(arizona->regmap, base + 0x9, | ||
1380 | ARIZONA_FLL1_GAIN_MASK, | ||
1381 | cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); | ||
1382 | |||
1105 | regmap_update_bits(arizona->regmap, base + 2, | 1383 | regmap_update_bits(arizona->regmap, base + 2, |
1106 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, | 1384 | ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, |
1107 | ARIZONA_FLL1_CTRL_UPD | cfg->n); | 1385 | ARIZONA_FLL1_CTRL_UPD | cfg->n); |
1108 | } | 1386 | } |
1109 | 1387 | ||
1110 | int arizona_set_fll(struct arizona_fll *fll, int source, | 1388 | static bool arizona_is_enabled_fll(struct arizona_fll *fll) |
1111 | unsigned int Fref, unsigned int Fout) | ||
1112 | { | 1389 | { |
1113 | struct arizona *arizona = fll->arizona; | 1390 | struct arizona *arizona = fll->arizona; |
1114 | struct arizona_fll_cfg cfg, sync; | 1391 | unsigned int reg; |
1115 | unsigned int reg, val; | ||
1116 | int syncsrc; | ||
1117 | bool ena; | ||
1118 | int ret; | 1392 | int ret; |
1119 | 1393 | ||
1120 | if (fll->fref == Fref && fll->fout == Fout) | ||
1121 | return 0; | ||
1122 | |||
1123 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); | 1394 | ret = regmap_read(arizona->regmap, fll->base + 1, ®); |
1124 | if (ret != 0) { | 1395 | if (ret != 0) { |
1125 | arizona_fll_err(fll, "Failed to read current state: %d\n", | 1396 | arizona_fll_err(fll, "Failed to read current state: %d\n", |
1126 | ret); | 1397 | ret); |
1127 | return ret; | 1398 | return ret; |
1128 | } | 1399 | } |
1129 | ena = reg & ARIZONA_FLL1_ENA; | ||
1130 | 1400 | ||
1131 | if (Fout) { | 1401 | return reg & ARIZONA_FLL1_ENA; |
1132 | /* Do we have a 32kHz reference? */ | 1402 | } |
1133 | regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); | ||
1134 | switch (val & ARIZONA_CLK_32K_SRC_MASK) { | ||
1135 | case ARIZONA_CLK_SRC_MCLK1: | ||
1136 | case ARIZONA_CLK_SRC_MCLK2: | ||
1137 | syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; | ||
1138 | break; | ||
1139 | default: | ||
1140 | syncsrc = -1; | ||
1141 | } | ||
1142 | 1403 | ||
1143 | if (source == syncsrc) | 1404 | static void arizona_enable_fll(struct arizona_fll *fll, |
1144 | syncsrc = -1; | 1405 | struct arizona_fll_cfg *ref, |
1406 | struct arizona_fll_cfg *sync) | ||
1407 | { | ||
1408 | struct arizona *arizona = fll->arizona; | ||
1409 | int ret; | ||
1145 | 1410 | ||
1146 | if (syncsrc >= 0) { | 1411 | /* |
1147 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | 1412 | * If we have both REFCLK and SYNCCLK then enable both, |
1148 | if (ret != 0) | 1413 | * otherwise apply the SYNCCLK settings to REFCLK. |
1149 | return ret; | 1414 | */ |
1415 | if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) { | ||
1416 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
1417 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1418 | ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1419 | |||
1420 | arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, | ||
1421 | false); | ||
1422 | if (fll->sync_src >= 0) | ||
1423 | arizona_apply_fll(arizona, fll->base + 0x10, sync, | ||
1424 | fll->sync_src, true); | ||
1425 | } else if (fll->sync_src >= 0) { | ||
1426 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
1427 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1428 | sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1429 | |||
1430 | arizona_apply_fll(arizona, fll->base, sync, | ||
1431 | fll->sync_src, false); | ||
1150 | 1432 | ||
1151 | ret = arizona_calc_fll(fll, &cfg, 32768, Fout); | ||
1152 | if (ret != 0) | ||
1153 | return ret; | ||
1154 | } else { | ||
1155 | ret = arizona_calc_fll(fll, &cfg, Fref, Fout); | ||
1156 | if (ret != 0) | ||
1157 | return ret; | ||
1158 | } | ||
1159 | } else { | ||
1160 | regmap_update_bits(arizona->regmap, fll->base + 1, | ||
1161 | ARIZONA_FLL1_ENA, 0); | ||
1162 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1433 | regmap_update_bits(arizona->regmap, fll->base + 0x11, |
1163 | ARIZONA_FLL1_SYNC_ENA, 0); | 1434 | ARIZONA_FLL1_SYNC_ENA, 0); |
1164 | |||
1165 | if (ena) | ||
1166 | pm_runtime_put_autosuspend(arizona->dev); | ||
1167 | |||
1168 | fll->fref = Fref; | ||
1169 | fll->fout = Fout; | ||
1170 | |||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | regmap_update_bits(arizona->regmap, fll->base + 5, | ||
1175 | ARIZONA_FLL1_OUTDIV_MASK, | ||
1176 | cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); | ||
1177 | |||
1178 | if (syncsrc >= 0) { | ||
1179 | arizona_apply_fll(arizona, fll->base, &cfg, syncsrc); | ||
1180 | arizona_apply_fll(arizona, fll->base + 0x10, &sync, source); | ||
1181 | } else { | 1435 | } else { |
1182 | arizona_apply_fll(arizona, fll->base, &cfg, source); | 1436 | arizona_fll_err(fll, "No clocks provided\n"); |
1437 | return; | ||
1183 | } | 1438 | } |
1184 | 1439 | ||
1185 | if (!ena) | 1440 | /* |
1441 | * Increase the bandwidth if we're not using a low frequency | ||
1442 | * sync source. | ||
1443 | */ | ||
1444 | if (fll->sync_src >= 0 && fll->sync_freq > 100000) | ||
1445 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | ||
1446 | ARIZONA_FLL1_SYNC_BW, 0); | ||
1447 | else | ||
1448 | regmap_update_bits(arizona->regmap, fll->base + 0x17, | ||
1449 | ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); | ||
1450 | |||
1451 | if (!arizona_is_enabled_fll(fll)) | ||
1186 | pm_runtime_get(arizona->dev); | 1452 | pm_runtime_get(arizona->dev); |
1187 | 1453 | ||
1188 | /* Clear any pending completions */ | 1454 | /* Clear any pending completions */ |
@@ -1190,7 +1456,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1190 | 1456 | ||
1191 | regmap_update_bits(arizona->regmap, fll->base + 1, | 1457 | regmap_update_bits(arizona->regmap, fll->base + 1, |
1192 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); | 1458 | ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); |
1193 | if (syncsrc >= 0) | 1459 | if (fll->ref_src >= 0 && fll->sync_src >= 0 && |
1460 | fll->ref_src != fll->sync_src) | ||
1194 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | 1461 | regmap_update_bits(arizona->regmap, fll->base + 0x11, |
1195 | ARIZONA_FLL1_SYNC_ENA, | 1462 | ARIZONA_FLL1_SYNC_ENA, |
1196 | ARIZONA_FLL1_SYNC_ENA); | 1463 | ARIZONA_FLL1_SYNC_ENA); |
@@ -1199,10 +1466,88 @@ int arizona_set_fll(struct arizona_fll *fll, int source, | |||
1199 | msecs_to_jiffies(250)); | 1466 | msecs_to_jiffies(250)); |
1200 | if (ret == 0) | 1467 | if (ret == 0) |
1201 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); | 1468 | arizona_fll_warn(fll, "Timed out waiting for lock\n"); |
1469 | } | ||
1470 | |||
1471 | static void arizona_disable_fll(struct arizona_fll *fll) | ||
1472 | { | ||
1473 | struct arizona *arizona = fll->arizona; | ||
1474 | bool change; | ||
1475 | |||
1476 | regmap_update_bits_check(arizona->regmap, fll->base + 1, | ||
1477 | ARIZONA_FLL1_ENA, 0, &change); | ||
1478 | regmap_update_bits(arizona->regmap, fll->base + 0x11, | ||
1479 | ARIZONA_FLL1_SYNC_ENA, 0); | ||
1480 | |||
1481 | if (change) | ||
1482 | pm_runtime_put_autosuspend(arizona->dev); | ||
1483 | } | ||
1484 | |||
1485 | int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | ||
1486 | unsigned int Fref, unsigned int Fout) | ||
1487 | { | ||
1488 | struct arizona_fll_cfg ref, sync; | ||
1489 | int ret; | ||
1202 | 1490 | ||
1203 | fll->fref = Fref; | 1491 | if (fll->ref_src == source && fll->ref_freq == Fref) |
1492 | return 0; | ||
1493 | |||
1494 | if (fll->fout && Fref > 0) { | ||
1495 | ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); | ||
1496 | if (ret != 0) | ||
1497 | return ret; | ||
1498 | |||
1499 | if (fll->sync_src >= 0) { | ||
1500 | ret = arizona_calc_fll(fll, &sync, fll->sync_freq, | ||
1501 | fll->fout); | ||
1502 | if (ret != 0) | ||
1503 | return ret; | ||
1504 | } | ||
1505 | } | ||
1506 | |||
1507 | fll->ref_src = source; | ||
1508 | fll->ref_freq = Fref; | ||
1509 | |||
1510 | if (fll->fout && Fref > 0) { | ||
1511 | arizona_enable_fll(fll, &ref, &sync); | ||
1512 | } | ||
1513 | |||
1514 | return 0; | ||
1515 | } | ||
1516 | EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); | ||
1517 | |||
1518 | int arizona_set_fll(struct arizona_fll *fll, int source, | ||
1519 | unsigned int Fref, unsigned int Fout) | ||
1520 | { | ||
1521 | struct arizona_fll_cfg ref, sync; | ||
1522 | int ret; | ||
1523 | |||
1524 | if (fll->sync_src == source && | ||
1525 | fll->sync_freq == Fref && fll->fout == Fout) | ||
1526 | return 0; | ||
1527 | |||
1528 | if (Fout) { | ||
1529 | if (fll->ref_src >= 0) { | ||
1530 | ret = arizona_calc_fll(fll, &ref, fll->ref_freq, | ||
1531 | Fout); | ||
1532 | if (ret != 0) | ||
1533 | return ret; | ||
1534 | } | ||
1535 | |||
1536 | ret = arizona_calc_fll(fll, &sync, Fref, Fout); | ||
1537 | if (ret != 0) | ||
1538 | return ret; | ||
1539 | } | ||
1540 | |||
1541 | fll->sync_src = source; | ||
1542 | fll->sync_freq = Fref; | ||
1204 | fll->fout = Fout; | 1543 | fll->fout = Fout; |
1205 | 1544 | ||
1545 | if (Fout) { | ||
1546 | arizona_enable_fll(fll, &ref, &sync); | ||
1547 | } else { | ||
1548 | arizona_disable_fll(fll); | ||
1549 | } | ||
1550 | |||
1206 | return 0; | 1551 | return 0; |
1207 | } | 1552 | } |
1208 | EXPORT_SYMBOL_GPL(arizona_set_fll); | 1553 | EXPORT_SYMBOL_GPL(arizona_set_fll); |
@@ -1211,12 +1556,26 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, | |||
1211 | int ok_irq, struct arizona_fll *fll) | 1556 | int ok_irq, struct arizona_fll *fll) |
1212 | { | 1557 | { |
1213 | int ret; | 1558 | int ret; |
1559 | unsigned int val; | ||
1214 | 1560 | ||
1215 | init_completion(&fll->ok); | 1561 | init_completion(&fll->ok); |
1216 | 1562 | ||
1217 | fll->id = id; | 1563 | fll->id = id; |
1218 | fll->base = base; | 1564 | fll->base = base; |
1219 | fll->arizona = arizona; | 1565 | fll->arizona = arizona; |
1566 | fll->sync_src = ARIZONA_FLL_SRC_NONE; | ||
1567 | |||
1568 | /* Configure default refclk to 32kHz if we have one */ | ||
1569 | regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); | ||
1570 | switch (val & ARIZONA_CLK_32K_SRC_MASK) { | ||
1571 | case ARIZONA_CLK_SRC_MCLK1: | ||
1572 | case ARIZONA_CLK_SRC_MCLK2: | ||
1573 | fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; | ||
1574 | break; | ||
1575 | default: | ||
1576 | fll->ref_src = ARIZONA_FLL_SRC_NONE; | ||
1577 | } | ||
1578 | fll->ref_freq = 32768; | ||
1220 | 1579 | ||
1221 | snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); | 1580 | snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); |
1222 | snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), | 1581 | snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 13dd2916b721..af39f1006427 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #define ARIZONA_CLK_SRC_AIF2BCLK 0x9 | 32 | #define ARIZONA_CLK_SRC_AIF2BCLK 0x9 |
33 | #define ARIZONA_CLK_SRC_AIF3BCLK 0xa | 33 | #define ARIZONA_CLK_SRC_AIF3BCLK 0xa |
34 | 34 | ||
35 | #define ARIZONA_FLL_SRC_NONE -1 | ||
35 | #define ARIZONA_FLL_SRC_MCLK1 0 | 36 | #define ARIZONA_FLL_SRC_MCLK1 0 |
36 | #define ARIZONA_FLL_SRC_MCLK2 1 | 37 | #define ARIZONA_FLL_SRC_MCLK2 1 |
37 | #define ARIZONA_FLL_SRC_SLIMCLK 3 | 38 | #define ARIZONA_FLL_SRC_SLIMCLK 3 |
@@ -48,6 +49,14 @@ | |||
48 | #define ARIZONA_MIXER_VOL_SHIFT 1 | 49 | #define ARIZONA_MIXER_VOL_SHIFT 1 |
49 | #define ARIZONA_MIXER_VOL_WIDTH 7 | 50 | #define ARIZONA_MIXER_VOL_WIDTH 7 |
50 | 51 | ||
52 | #define ARIZONA_CLK_6MHZ 0 | ||
53 | #define ARIZONA_CLK_12MHZ 1 | ||
54 | #define ARIZONA_CLK_24MHZ 2 | ||
55 | #define ARIZONA_CLK_49MHZ 3 | ||
56 | #define ARIZONA_CLK_73MHZ 4 | ||
57 | #define ARIZONA_CLK_98MHZ 5 | ||
58 | #define ARIZONA_CLK_147MHZ 6 | ||
59 | |||
51 | #define ARIZONA_MAX_DAI 4 | 60 | #define ARIZONA_MAX_DAI 4 |
52 | #define ARIZONA_MAX_ADSP 4 | 61 | #define ARIZONA_MAX_ADSP 4 |
53 | 62 | ||
@@ -64,6 +73,12 @@ struct arizona_priv { | |||
64 | int sysclk; | 73 | int sysclk; |
65 | int asyncclk; | 74 | int asyncclk; |
66 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; | 75 | struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; |
76 | |||
77 | int num_inputs; | ||
78 | unsigned int in_pending; | ||
79 | |||
80 | unsigned int spk_ena:2; | ||
81 | unsigned int spk_ena_pending:1; | ||
67 | }; | 82 | }; |
68 | 83 | ||
69 | #define ARIZONA_NUM_MIXER_INPUTS 99 | 84 | #define ARIZONA_NUM_MIXER_INPUTS 99 |
@@ -165,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
165 | ARIZONA_MIXER_ROUTES(name, name "L"), \ | 180 | ARIZONA_MIXER_ROUTES(name, name "L"), \ |
166 | ARIZONA_MIXER_ROUTES(name, name "R") | 181 | ARIZONA_MIXER_ROUTES(name, name "R") |
167 | 182 | ||
183 | #define ARIZONA_RATE_ENUM_SIZE 4 | ||
184 | extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; | ||
185 | extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; | ||
186 | |||
187 | extern const struct soc_enum arizona_isrc_fsl[]; | ||
188 | |||
168 | extern const struct soc_enum arizona_in_vi_ramp; | 189 | extern const struct soc_enum arizona_in_vi_ramp; |
169 | extern const struct soc_enum arizona_in_vd_ramp; | 190 | extern const struct soc_enum arizona_in_vd_ramp; |
170 | 191 | ||
@@ -201,8 +222,12 @@ struct arizona_fll { | |||
201 | unsigned int base; | 222 | unsigned int base; |
202 | unsigned int vco_mult; | 223 | unsigned int vco_mult; |
203 | struct completion ok; | 224 | struct completion ok; |
204 | unsigned int fref; | 225 | |
205 | unsigned int fout; | 226 | unsigned int fout; |
227 | int sync_src; | ||
228 | unsigned int sync_freq; | ||
229 | int ref_src; | ||
230 | unsigned int ref_freq; | ||
206 | 231 | ||
207 | char lock_name[ARIZONA_FLL_NAME_LEN]; | 232 | char lock_name[ARIZONA_FLL_NAME_LEN]; |
208 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; | 233 | char clock_ok_name[ARIZONA_FLL_NAME_LEN]; |
@@ -210,9 +235,13 @@ struct arizona_fll { | |||
210 | 235 | ||
211 | extern int arizona_init_fll(struct arizona *arizona, int id, int base, | 236 | extern int arizona_init_fll(struct arizona *arizona, int id, int base, |
212 | int lock_irq, int ok_irq, struct arizona_fll *fll); | 237 | int lock_irq, int ok_irq, struct arizona_fll *fll); |
238 | extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, | ||
239 | unsigned int Fref, unsigned int Fout); | ||
213 | extern int arizona_set_fll(struct arizona_fll *fll, int source, | 240 | extern int arizona_set_fll(struct arizona_fll *fll, int source, |
214 | unsigned int Fref, unsigned int Fout); | 241 | unsigned int Fref, unsigned int Fout); |
215 | 242 | ||
243 | extern int arizona_init_spk(struct snd_soc_codec *codec); | ||
244 | |||
216 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); | 245 | extern int arizona_init_dai(struct arizona_priv *priv, int dai); |
217 | 246 | ||
218 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, | 247 | int arizona_set_output_mode(struct snd_soc_codec *codec, int output, |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 2415a4118dbd..03036b326732 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -39,17 +39,15 @@ | |||
39 | 39 | ||
40 | /* | 40 | /* |
41 | * CS4271 registers | 41 | * CS4271 registers |
42 | * High byte represents SPI chip address (0x10) + write command (0) | ||
43 | * Low byte - codec register address | ||
44 | */ | 42 | */ |
45 | #define CS4271_MODE1 0x2001 /* Mode Control 1 */ | 43 | #define CS4271_MODE1 0x01 /* Mode Control 1 */ |
46 | #define CS4271_DACCTL 0x2002 /* DAC Control */ | 44 | #define CS4271_DACCTL 0x02 /* DAC Control */ |
47 | #define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */ | 45 | #define CS4271_DACVOL 0x03 /* DAC Volume & Mixing Control */ |
48 | #define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */ | 46 | #define CS4271_VOLA 0x04 /* DAC Channel A Volume Control */ |
49 | #define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */ | 47 | #define CS4271_VOLB 0x05 /* DAC Channel B Volume Control */ |
50 | #define CS4271_ADCCTL 0x2006 /* ADC Control */ | 48 | #define CS4271_ADCCTL 0x06 /* ADC Control */ |
51 | #define CS4271_MODE2 0x2007 /* Mode Control 2 */ | 49 | #define CS4271_MODE2 0x07 /* Mode Control 2 */ |
52 | #define CS4271_CHIPID 0x2008 /* Chip ID */ | 50 | #define CS4271_CHIPID 0x08 /* Chip ID */ |
53 | 51 | ||
54 | #define CS4271_FIRSTREG CS4271_MODE1 | 52 | #define CS4271_FIRSTREG CS4271_MODE1 |
55 | #define CS4271_LASTREG CS4271_MODE2 | 53 | #define CS4271_LASTREG CS4271_MODE2 |
@@ -144,23 +142,27 @@ | |||
144 | * Array do not include Chip ID, as codec driver does not use | 142 | * Array do not include Chip ID, as codec driver does not use |
145 | * registers read operations at all | 143 | * registers read operations at all |
146 | */ | 144 | */ |
147 | static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = { | 145 | static const struct reg_default cs4271_reg_defaults[] = { |
148 | 0, | 146 | { CS4271_MODE1, 0, }, |
149 | 0, | 147 | { CS4271_DACCTL, CS4271_DACCTL_AMUTE, }, |
150 | CS4271_DACCTL_AMUTE, | 148 | { CS4271_DACVOL, CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, }, |
151 | CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, | 149 | { CS4271_VOLA, 0, }, |
152 | 0, | 150 | { CS4271_VOLB, 0, }, |
153 | 0, | 151 | { CS4271_ADCCTL, 0, }, |
154 | 0, | 152 | { CS4271_MODE2, 0, }, |
155 | 0, | ||
156 | }; | 153 | }; |
157 | 154 | ||
155 | static bool cs4271_volatile_reg(struct device *dev, unsigned int reg) | ||
156 | { | ||
157 | return reg == CS4271_CHIPID; | ||
158 | } | ||
159 | |||
158 | struct cs4271_private { | 160 | struct cs4271_private { |
159 | /* SND_SOC_I2C or SND_SOC_SPI */ | 161 | /* SND_SOC_I2C or SND_SOC_SPI */ |
160 | enum snd_soc_control_type bus_type; | ||
161 | unsigned int mclk; | 162 | unsigned int mclk; |
162 | bool master; | 163 | bool master; |
163 | bool deemph; | 164 | bool deemph; |
165 | struct regmap *regmap; | ||
164 | /* Current sample rate for de-emphasis control */ | 166 | /* Current sample rate for de-emphasis control */ |
165 | int rate; | 167 | int rate; |
166 | /* GPIO driving Reset pin, if any */ | 168 | /* GPIO driving Reset pin, if any */ |
@@ -210,14 +212,14 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
210 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | 212 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { |
211 | case SND_SOC_DAIFMT_LEFT_J: | 213 | case SND_SOC_DAIFMT_LEFT_J: |
212 | val |= CS4271_MODE1_DAC_DIF_LJ; | 214 | val |= CS4271_MODE1_DAC_DIF_LJ; |
213 | ret = snd_soc_update_bits(codec, CS4271_ADCCTL, | 215 | ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL, |
214 | CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ); | 216 | CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ); |
215 | if (ret < 0) | 217 | if (ret < 0) |
216 | return ret; | 218 | return ret; |
217 | break; | 219 | break; |
218 | case SND_SOC_DAIFMT_I2S: | 220 | case SND_SOC_DAIFMT_I2S: |
219 | val |= CS4271_MODE1_DAC_DIF_I2S; | 221 | val |= CS4271_MODE1_DAC_DIF_I2S; |
220 | ret = snd_soc_update_bits(codec, CS4271_ADCCTL, | 222 | ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL, |
221 | CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S); | 223 | CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S); |
222 | if (ret < 0) | 224 | if (ret < 0) |
223 | return ret; | 225 | return ret; |
@@ -227,7 +229,7 @@ static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
227 | return -EINVAL; | 229 | return -EINVAL; |
228 | } | 230 | } |
229 | 231 | ||
230 | ret = snd_soc_update_bits(codec, CS4271_MODE1, | 232 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1, |
231 | CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val); | 233 | CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val); |
232 | if (ret < 0) | 234 | if (ret < 0) |
233 | return ret; | 235 | return ret; |
@@ -252,7 +254,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec) | |||
252 | val <<= 4; | 254 | val <<= 4; |
253 | } | 255 | } |
254 | 256 | ||
255 | ret = snd_soc_update_bits(codec, CS4271_DACCTL, | 257 | ret = regmap_update_bits(cs4271->regmap, CS4271_DACCTL, |
256 | CS4271_DACCTL_DEM_MASK, val); | 258 | CS4271_DACCTL_DEM_MASK, val); |
257 | if (ret < 0) | 259 | if (ret < 0) |
258 | return ret; | 260 | return ret; |
@@ -341,14 +343,14 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream, | |||
341 | !dai->capture_active) || | 343 | !dai->capture_active) || |
342 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE && | 344 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE && |
343 | !dai->playback_active)) { | 345 | !dai->playback_active)) { |
344 | ret = snd_soc_update_bits(codec, CS4271_MODE2, | 346 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
345 | CS4271_MODE2_PDN, | 347 | CS4271_MODE2_PDN, |
346 | CS4271_MODE2_PDN); | 348 | CS4271_MODE2_PDN); |
347 | if (ret < 0) | 349 | if (ret < 0) |
348 | return ret; | 350 | return ret; |
349 | 351 | ||
350 | ret = snd_soc_update_bits(codec, CS4271_MODE2, | 352 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
351 | CS4271_MODE2_PDN, 0); | 353 | CS4271_MODE2_PDN, 0); |
352 | if (ret < 0) | 354 | if (ret < 0) |
353 | return ret; | 355 | return ret; |
354 | } | 356 | } |
@@ -378,7 +380,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream, | |||
378 | 380 | ||
379 | val |= cs4271_clk_tab[i].ratio_mask; | 381 | val |= cs4271_clk_tab[i].ratio_mask; |
380 | 382 | ||
381 | ret = snd_soc_update_bits(codec, CS4271_MODE1, | 383 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1, |
382 | CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); | 384 | CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val); |
383 | if (ret < 0) | 385 | if (ret < 0) |
384 | return ret; | 386 | return ret; |
@@ -386,22 +388,29 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream, | |||
386 | return cs4271_set_deemph(codec); | 388 | return cs4271_set_deemph(codec); |
387 | } | 389 | } |
388 | 390 | ||
389 | static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute) | 391 | static int cs4271_mute_stream(struct snd_soc_dai *dai, int mute, int stream) |
390 | { | 392 | { |
391 | struct snd_soc_codec *codec = dai->codec; | 393 | struct snd_soc_codec *codec = dai->codec; |
394 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | ||
392 | int ret; | 395 | int ret; |
393 | int val_a = 0; | 396 | int val_a = 0; |
394 | int val_b = 0; | 397 | int val_b = 0; |
395 | 398 | ||
399 | if (stream != SNDRV_PCM_STREAM_PLAYBACK) | ||
400 | return 0; | ||
401 | |||
396 | if (mute) { | 402 | if (mute) { |
397 | val_a = CS4271_VOLA_MUTE; | 403 | val_a = CS4271_VOLA_MUTE; |
398 | val_b = CS4271_VOLB_MUTE; | 404 | val_b = CS4271_VOLB_MUTE; |
399 | } | 405 | } |
400 | 406 | ||
401 | ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a); | 407 | ret = regmap_update_bits(cs4271->regmap, CS4271_VOLA, |
408 | CS4271_VOLA_MUTE, val_a); | ||
402 | if (ret < 0) | 409 | if (ret < 0) |
403 | return ret; | 410 | return ret; |
404 | ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b); | 411 | |
412 | ret = regmap_update_bits(cs4271->regmap, CS4271_VOLB, | ||
413 | CS4271_VOLB_MUTE, val_b); | ||
405 | if (ret < 0) | 414 | if (ret < 0) |
406 | return ret; | 415 | return ret; |
407 | 416 | ||
@@ -436,7 +445,7 @@ static const struct snd_soc_dai_ops cs4271_dai_ops = { | |||
436 | .hw_params = cs4271_hw_params, | 445 | .hw_params = cs4271_hw_params, |
437 | .set_sysclk = cs4271_set_dai_sysclk, | 446 | .set_sysclk = cs4271_set_dai_sysclk, |
438 | .set_fmt = cs4271_set_dai_fmt, | 447 | .set_fmt = cs4271_set_dai_fmt, |
439 | .digital_mute = cs4271_digital_mute, | 448 | .mute_stream = cs4271_mute_stream, |
440 | }; | 449 | }; |
441 | 450 | ||
442 | static struct snd_soc_dai_driver cs4271_dai = { | 451 | static struct snd_soc_dai_driver cs4271_dai = { |
@@ -463,25 +472,33 @@ static struct snd_soc_dai_driver cs4271_dai = { | |||
463 | static int cs4271_soc_suspend(struct snd_soc_codec *codec) | 472 | static int cs4271_soc_suspend(struct snd_soc_codec *codec) |
464 | { | 473 | { |
465 | int ret; | 474 | int ret; |
475 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | ||
476 | |||
466 | /* Set power-down bit */ | 477 | /* Set power-down bit */ |
467 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, | 478 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
468 | CS4271_MODE2_PDN); | 479 | CS4271_MODE2_PDN, CS4271_MODE2_PDN); |
469 | if (ret < 0) | 480 | if (ret < 0) |
470 | return ret; | 481 | return ret; |
482 | |||
471 | return 0; | 483 | return 0; |
472 | } | 484 | } |
473 | 485 | ||
474 | static int cs4271_soc_resume(struct snd_soc_codec *codec) | 486 | static int cs4271_soc_resume(struct snd_soc_codec *codec) |
475 | { | 487 | { |
476 | int ret; | 488 | int ret; |
489 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | ||
490 | |||
477 | /* Restore codec state */ | 491 | /* Restore codec state */ |
478 | ret = snd_soc_cache_sync(codec); | 492 | ret = regcache_sync(cs4271->regmap); |
479 | if (ret < 0) | 493 | if (ret < 0) |
480 | return ret; | 494 | return ret; |
495 | |||
481 | /* then disable the power-down bit */ | 496 | /* then disable the power-down bit */ |
482 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); | 497 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
498 | CS4271_MODE2_PDN, 0); | ||
483 | if (ret < 0) | 499 | if (ret < 0) |
484 | return ret; | 500 | return ret; |
501 | |||
485 | return 0; | 502 | return 0; |
486 | } | 503 | } |
487 | #else | 504 | #else |
@@ -542,40 +559,22 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
542 | 559 | ||
543 | cs4271->gpio_nreset = gpio_nreset; | 560 | cs4271->gpio_nreset = gpio_nreset; |
544 | 561 | ||
545 | /* | 562 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
546 | * In case of I2C, chip address specified in board data. | 563 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, |
547 | * So cache IO operations use 8 bit codec register address. | 564 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); |
548 | * In case of SPI, chip address and register address | ||
549 | * passed together as 16 bit value. | ||
550 | * Anyway, register address is masked with 0xFF inside | ||
551 | * soc-cache code. | ||
552 | */ | ||
553 | if (cs4271->bus_type == SND_SOC_SPI) | ||
554 | ret = snd_soc_codec_set_cache_io(codec, 16, 8, | ||
555 | cs4271->bus_type); | ||
556 | else | ||
557 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, | ||
558 | cs4271->bus_type); | ||
559 | if (ret) { | ||
560 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
561 | return ret; | ||
562 | } | ||
563 | |||
564 | ret = snd_soc_update_bits(codec, CS4271_MODE2, | ||
565 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, | ||
566 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); | ||
567 | if (ret < 0) | 565 | if (ret < 0) |
568 | return ret; | 566 | return ret; |
569 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); | 567 | ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
568 | CS4271_MODE2_PDN, 0); | ||
570 | if (ret < 0) | 569 | if (ret < 0) |
571 | return ret; | 570 | return ret; |
572 | /* Power-up sequence requires 85 uS */ | 571 | /* Power-up sequence requires 85 uS */ |
573 | udelay(85); | 572 | udelay(85); |
574 | 573 | ||
575 | if (amutec_eq_bmutec) | 574 | if (amutec_eq_bmutec) |
576 | snd_soc_update_bits(codec, CS4271_MODE2, | 575 | regmap_update_bits(cs4271->regmap, CS4271_MODE2, |
577 | CS4271_MODE2_MUTECAEQUB, | 576 | CS4271_MODE2_MUTECAEQUB, |
578 | CS4271_MODE2_MUTECAEQUB); | 577 | CS4271_MODE2_MUTECAEQUB); |
579 | 578 | ||
580 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, | 579 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, |
581 | ARRAY_SIZE(cs4271_snd_controls)); | 580 | ARRAY_SIZE(cs4271_snd_controls)); |
@@ -597,13 +596,24 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | |||
597 | .remove = cs4271_remove, | 596 | .remove = cs4271_remove, |
598 | .suspend = cs4271_soc_suspend, | 597 | .suspend = cs4271_soc_suspend, |
599 | .resume = cs4271_soc_resume, | 598 | .resume = cs4271_soc_resume, |
600 | .reg_cache_default = cs4271_dflt_reg, | ||
601 | .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg), | ||
602 | .reg_word_size = sizeof(cs4271_dflt_reg[0]), | ||
603 | .compress_type = SND_SOC_FLAT_COMPRESSION, | ||
604 | }; | 599 | }; |
605 | 600 | ||
606 | #if defined(CONFIG_SPI_MASTER) | 601 | #if defined(CONFIG_SPI_MASTER) |
602 | |||
603 | static const struct regmap_config cs4271_spi_regmap = { | ||
604 | .reg_bits = 16, | ||
605 | .val_bits = 8, | ||
606 | .max_register = CS4271_LASTREG, | ||
607 | .read_flag_mask = 0x21, | ||
608 | .write_flag_mask = 0x20, | ||
609 | |||
610 | .reg_defaults = cs4271_reg_defaults, | ||
611 | .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), | ||
612 | .cache_type = REGCACHE_RBTREE, | ||
613 | |||
614 | .volatile_reg = cs4271_volatile_reg, | ||
615 | }; | ||
616 | |||
607 | static int cs4271_spi_probe(struct spi_device *spi) | 617 | static int cs4271_spi_probe(struct spi_device *spi) |
608 | { | 618 | { |
609 | struct cs4271_private *cs4271; | 619 | struct cs4271_private *cs4271; |
@@ -613,7 +623,9 @@ static int cs4271_spi_probe(struct spi_device *spi) | |||
613 | return -ENOMEM; | 623 | return -ENOMEM; |
614 | 624 | ||
615 | spi_set_drvdata(spi, cs4271); | 625 | spi_set_drvdata(spi, cs4271); |
616 | cs4271->bus_type = SND_SOC_SPI; | 626 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); |
627 | if (IS_ERR(cs4271->regmap)) | ||
628 | return PTR_ERR(cs4271->regmap); | ||
617 | 629 | ||
618 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, | 630 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, |
619 | &cs4271_dai, 1); | 631 | &cs4271_dai, 1); |
@@ -643,6 +655,18 @@ static const struct i2c_device_id cs4271_i2c_id[] = { | |||
643 | }; | 655 | }; |
644 | MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); | 656 | MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); |
645 | 657 | ||
658 | static const struct regmap_config cs4271_i2c_regmap = { | ||
659 | .reg_bits = 8, | ||
660 | .val_bits = 8, | ||
661 | .max_register = CS4271_LASTREG, | ||
662 | |||
663 | .reg_defaults = cs4271_reg_defaults, | ||
664 | .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), | ||
665 | .cache_type = REGCACHE_RBTREE, | ||
666 | |||
667 | .volatile_reg = cs4271_volatile_reg, | ||
668 | }; | ||
669 | |||
646 | static int cs4271_i2c_probe(struct i2c_client *client, | 670 | static int cs4271_i2c_probe(struct i2c_client *client, |
647 | const struct i2c_device_id *id) | 671 | const struct i2c_device_id *id) |
648 | { | 672 | { |
@@ -653,7 +677,9 @@ static int cs4271_i2c_probe(struct i2c_client *client, | |||
653 | return -ENOMEM; | 677 | return -ENOMEM; |
654 | 678 | ||
655 | i2c_set_clientdata(client, cs4271); | 679 | i2c_set_clientdata(client, cs4271); |
656 | cs4271->bus_type = SND_SOC_I2C; | 680 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); |
681 | if (IS_ERR(cs4271->regmap)) | ||
682 | return PTR_ERR(cs4271->regmap); | ||
657 | 683 | ||
658 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, | 684 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, |
659 | &cs4271_dai, 1); | 685 | &cs4271_dai, 1); |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 6361dab48bd1..3b20c86cdb01 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1180,7 +1180,11 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, | |||
1180 | priv->config[id].mmcc &= 0xC0; | 1180 | priv->config[id].mmcc &= 0xC0; |
1181 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; | 1181 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; |
1182 | priv->config[id].spc &= 0xFC; | 1182 | priv->config[id].spc &= 0xFC; |
1183 | priv->config[id].spc |= MCK_SCLK_MCLK; | 1183 | /* Use SCLK=64*Fs if internal MCLK >= 6.4MHz */ |
1184 | if (priv->mclk >= 6400000) | ||
1185 | priv->config[id].spc |= MCK_SCLK_64FS; | ||
1186 | else | ||
1187 | priv->config[id].spc |= MCK_SCLK_MCLK; | ||
1184 | } else { | 1188 | } else { |
1185 | /* CS42L73 Slave */ | 1189 | /* CS42L73 Slave */ |
1186 | priv->config[id].spc &= 0xFC; | 1190 | priv->config[id].spc &= 0xFC; |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index a4c16fd70f77..3eeada57e87d 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -739,14 +739,32 @@ static const unsigned int max98088_micboost_tlv[] = { | |||
739 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), | 739 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), |
740 | }; | 740 | }; |
741 | 741 | ||
742 | static const unsigned int max98088_hp_tlv[] = { | ||
743 | TLV_DB_RANGE_HEAD(5), | ||
744 | 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0), | ||
745 | 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0), | ||
746 | 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0), | ||
747 | 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0), | ||
748 | 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0), | ||
749 | }; | ||
750 | |||
751 | static const unsigned int max98088_spk_tlv[] = { | ||
752 | TLV_DB_RANGE_HEAD(5), | ||
753 | 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0), | ||
754 | 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0), | ||
755 | 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0), | ||
756 | 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0), | ||
757 | 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0), | ||
758 | }; | ||
759 | |||
742 | static const struct snd_kcontrol_new max98088_snd_controls[] = { | 760 | static const struct snd_kcontrol_new max98088_snd_controls[] = { |
743 | 761 | ||
744 | SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L, | 762 | SOC_DOUBLE_R_TLV("Headphone Volume", M98088_REG_39_LVL_HP_L, |
745 | M98088_REG_3A_LVL_HP_R, 0, 31, 0), | 763 | M98088_REG_3A_LVL_HP_R, 0, 31, 0, max98088_hp_tlv), |
746 | SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L, | 764 | SOC_DOUBLE_R_TLV("Speaker Volume", M98088_REG_3D_LVL_SPK_L, |
747 | M98088_REG_3E_LVL_SPK_R, 0, 31, 0), | 765 | M98088_REG_3E_LVL_SPK_R, 0, 31, 0, max98088_spk_tlv), |
748 | SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L, | 766 | SOC_DOUBLE_R_TLV("Receiver Volume", M98088_REG_3B_LVL_REC_L, |
749 | M98088_REG_3C_LVL_REC_R, 0, 31, 0), | 767 | M98088_REG_3C_LVL_REC_R, 0, 31, 0, max98088_spk_tlv), |
750 | 768 | ||
751 | SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L, | 769 | SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L, |
752 | M98088_REG_3A_LVL_HP_R, 7, 1, 1), | 770 | M98088_REG_3A_LVL_HP_R, 7, 1, 1), |
@@ -2006,7 +2024,7 @@ static int max98088_probe(struct snd_soc_codec *codec) | |||
2006 | ret); | 2024 | ret); |
2007 | goto err_access; | 2025 | goto err_access; |
2008 | } | 2026 | } |
2009 | dev_info(codec->dev, "revision %c\n", ret + 'A'); | 2027 | dev_info(codec->dev, "revision %c\n", ret - 0x40 + 'A'); |
2010 | 2028 | ||
2011 | snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV); | 2029 | snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV); |
2012 | 2030 | ||
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index fc176044994d..ce0d36412c97 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -23,8 +23,6 @@ | |||
23 | #include <sound/max98090.h> | 23 | #include <sound/max98090.h> |
24 | #include "max98090.h" | 24 | #include "max98090.h" |
25 | 25 | ||
26 | #include <linux/version.h> | ||
27 | |||
28 | #define DEBUG | 26 | #define DEBUG |
29 | #define EXTMIC_METHOD | 27 | #define EXTMIC_METHOD |
30 | #define EXTMIC_METHOD_TEST | 28 | #define EXTMIC_METHOD_TEST |
@@ -509,16 +507,16 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, | |||
509 | return 0; | 507 | return 0; |
510 | } | 508 | } |
511 | 509 | ||
512 | static const char * max98090_perf_pwr_text[] = | 510 | static const char *max98090_perf_pwr_text[] = |
513 | { "High Performance", "Low Power" }; | 511 | { "High Performance", "Low Power" }; |
514 | static const char * max98090_pwr_perf_text[] = | 512 | static const char *max98090_pwr_perf_text[] = |
515 | { "Low Power", "High Performance" }; | 513 | { "Low Power", "High Performance" }; |
516 | 514 | ||
517 | static const struct soc_enum max98090_vcmbandgap_enum = | 515 | static const struct soc_enum max98090_vcmbandgap_enum = |
518 | SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, | 516 | SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, |
519 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); | 517 | ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); |
520 | 518 | ||
521 | static const char * max98090_osr128_text[] = { "64*fs", "128*fs" }; | 519 | static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; |
522 | 520 | ||
523 | static const struct soc_enum max98090_osr128_enum = | 521 | static const struct soc_enum max98090_osr128_enum = |
524 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, | 522 | SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, |
@@ -535,28 +533,28 @@ static const struct soc_enum max98090_filter_dmic34mode_enum = | |||
535 | M98090_FLT_DMIC34MODE_SHIFT, | 533 | M98090_FLT_DMIC34MODE_SHIFT, |
536 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); | 534 | ARRAY_SIZE(max98090_mode_text), max98090_mode_text); |
537 | 535 | ||
538 | static const char * max98090_drcatk_text[] = | 536 | static const char *max98090_drcatk_text[] = |
539 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; | 537 | { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; |
540 | 538 | ||
541 | static const struct soc_enum max98090_drcatk_enum = | 539 | static const struct soc_enum max98090_drcatk_enum = |
542 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, | 540 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, |
543 | ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); | 541 | ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); |
544 | 542 | ||
545 | static const char * max98090_drcrls_text[] = | 543 | static const char *max98090_drcrls_text[] = |
546 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; | 544 | { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; |
547 | 545 | ||
548 | static const struct soc_enum max98090_drcrls_enum = | 546 | static const struct soc_enum max98090_drcrls_enum = |
549 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, | 547 | SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, |
550 | ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); | 548 | ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); |
551 | 549 | ||
552 | static const char * max98090_alccmp_text[] = | 550 | static const char *max98090_alccmp_text[] = |
553 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; | 551 | { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; |
554 | 552 | ||
555 | static const struct soc_enum max98090_alccmp_enum = | 553 | static const struct soc_enum max98090_alccmp_enum = |
556 | SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, | 554 | SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, |
557 | ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); | 555 | ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); |
558 | 556 | ||
559 | static const char * max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; | 557 | static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; |
560 | 558 | ||
561 | static const struct soc_enum max98090_drcexp_enum = | 559 | static const struct soc_enum max98090_drcexp_enum = |
562 | SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, | 560 | SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, |
@@ -859,7 +857,7 @@ static const struct soc_enum mic2_mux_enum = | |||
859 | static const struct snd_kcontrol_new max98090_mic2_mux = | 857 | static const struct snd_kcontrol_new max98090_mic2_mux = |
860 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); | 858 | SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); |
861 | 859 | ||
862 | static const char * max98090_micpre_text[] = { "Off", "On" }; | 860 | static const char *max98090_micpre_text[] = { "Off", "On" }; |
863 | 861 | ||
864 | static const struct soc_enum max98090_pa1en_enum = | 862 | static const struct soc_enum max98090_pa1en_enum = |
865 | SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, | 863 | SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, |
@@ -1703,9 +1701,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
1703 | * seen for the case of TDM mode. The remaining cases have | 1701 | * seen for the case of TDM mode. The remaining cases have |
1704 | * normal logic. | 1702 | * normal logic. |
1705 | */ | 1703 | */ |
1706 | if (max98090->tdm_slots > 1) { | 1704 | if (max98090->tdm_slots > 1) |
1707 | regval ^= M98090_BCI_MASK; | 1705 | regval ^= M98090_BCI_MASK; |
1708 | } | ||
1709 | 1706 | ||
1710 | snd_soc_write(codec, | 1707 | snd_soc_write(codec, |
1711 | M98090_REG_INTERFACE_FORMAT, regval); | 1708 | M98090_REG_INTERFACE_FORMAT, regval); |
@@ -2059,17 +2056,14 @@ static irqreturn_t max98090_interrupt(int irq, void *data) | |||
2059 | if (!active) | 2056 | if (!active) |
2060 | return IRQ_NONE; | 2057 | return IRQ_NONE; |
2061 | 2058 | ||
2062 | if (active & M98090_CLD_MASK) { | 2059 | if (active & M98090_CLD_MASK) |
2063 | dev_err(codec->dev, "M98090_CLD_MASK\n"); | 2060 | dev_err(codec->dev, "M98090_CLD_MASK\n"); |
2064 | } | ||
2065 | 2061 | ||
2066 | if (active & M98090_SLD_MASK) { | 2062 | if (active & M98090_SLD_MASK) |
2067 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); | 2063 | dev_dbg(codec->dev, "M98090_SLD_MASK\n"); |
2068 | } | ||
2069 | 2064 | ||
2070 | if (active & M98090_ULK_MASK) { | 2065 | if (active & M98090_ULK_MASK) |
2071 | dev_err(codec->dev, "M98090_ULK_MASK\n"); | 2066 | dev_err(codec->dev, "M98090_ULK_MASK\n"); |
2072 | } | ||
2073 | 2067 | ||
2074 | if (active & M98090_JDET_MASK) { | 2068 | if (active & M98090_JDET_MASK) { |
2075 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); | 2069 | dev_dbg(codec->dev, "M98090_JDET_MASK\n"); |
@@ -2080,13 +2074,11 @@ static irqreturn_t max98090_interrupt(int irq, void *data) | |||
2080 | msecs_to_jiffies(100)); | 2074 | msecs_to_jiffies(100)); |
2081 | } | 2075 | } |
2082 | 2076 | ||
2083 | if (active & M98090_DRCACT_MASK) { | 2077 | if (active & M98090_DRCACT_MASK) |
2084 | dev_dbg(codec->dev, "M98090_DRCACT_MASK\n"); | 2078 | dev_dbg(codec->dev, "M98090_DRCACT_MASK\n"); |
2085 | } | ||
2086 | 2079 | ||
2087 | if (active & M98090_DRCCLP_MASK) { | 2080 | if (active & M98090_DRCCLP_MASK) |
2088 | dev_err(codec->dev, "M98090_DRCCLP_MASK\n"); | 2081 | dev_err(codec->dev, "M98090_DRCCLP_MASK\n"); |
2089 | } | ||
2090 | 2082 | ||
2091 | return IRQ_HANDLED; | 2083 | return IRQ_HANDLED; |
2092 | } | 2084 | } |
@@ -2324,7 +2316,7 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2324 | max98090->pdata = i2c->dev.platform_data; | 2316 | max98090->pdata = i2c->dev.platform_data; |
2325 | max98090->irq = i2c->irq; | 2317 | max98090->irq = i2c->irq; |
2326 | 2318 | ||
2327 | max98090->regmap = regmap_init_i2c(i2c, &max98090_regmap); | 2319 | max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); |
2328 | if (IS_ERR(max98090->regmap)) { | 2320 | if (IS_ERR(max98090->regmap)) { |
2329 | ret = PTR_ERR(max98090->regmap); | 2321 | ret = PTR_ERR(max98090->regmap); |
2330 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | 2322 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); |
@@ -2334,18 +2326,13 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2334 | ret = snd_soc_register_codec(&i2c->dev, | 2326 | ret = snd_soc_register_codec(&i2c->dev, |
2335 | &soc_codec_dev_max98090, max98090_dai, | 2327 | &soc_codec_dev_max98090, max98090_dai, |
2336 | ARRAY_SIZE(max98090_dai)); | 2328 | ARRAY_SIZE(max98090_dai)); |
2337 | if (ret < 0) | ||
2338 | regmap_exit(max98090->regmap); | ||
2339 | |||
2340 | err_enable: | 2329 | err_enable: |
2341 | return ret; | 2330 | return ret; |
2342 | } | 2331 | } |
2343 | 2332 | ||
2344 | static int max98090_i2c_remove(struct i2c_client *client) | 2333 | static int max98090_i2c_remove(struct i2c_client *client) |
2345 | { | 2334 | { |
2346 | struct max98090_priv *max98090 = dev_get_drvdata(&client->dev); | ||
2347 | snd_soc_unregister_codec(&client->dev); | 2335 | snd_soc_unregister_codec(&client->dev); |
2348 | regmap_exit(max98090->regmap); | ||
2349 | return 0; | 2336 | return 0; |
2350 | } | 2337 | } |
2351 | 2338 | ||
@@ -2369,7 +2356,7 @@ static int max98090_runtime_suspend(struct device *dev) | |||
2369 | return 0; | 2356 | return 0; |
2370 | } | 2357 | } |
2371 | 2358 | ||
2372 | static struct dev_pm_ops max98090_pm = { | 2359 | static const struct dev_pm_ops max98090_pm = { |
2373 | SET_RUNTIME_PM_OPS(max98090_runtime_suspend, | 2360 | SET_RUNTIME_PM_OPS(max98090_runtime_suspend, |
2374 | max98090_runtime_resume, NULL) | 2361 | max98090_runtime_resume, NULL) |
2375 | }; | 2362 | }; |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 566ea3256e2d..721587c9cd84 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * sound/soc/codecs/si476x.c -- Codec driver for SI476X chips | ||
3 | * | ||
4 | * Copyright (C) 2012 Innovative Converged Devices(ICD) | ||
5 | * Copyright (C) 2013 Andrey Smirnov | ||
6 | * | ||
7 | * Author: Andrey Smirnov <andrew.smirnov@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
1 | #include <linux/module.h> | 20 | #include <linux/module.h> |
2 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
3 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -45,13 +64,23 @@ static unsigned int si476x_codec_read(struct snd_soc_codec *codec, | |||
45 | unsigned int reg) | 64 | unsigned int reg) |
46 | { | 65 | { |
47 | int err; | 66 | int err; |
67 | unsigned int val; | ||
48 | struct si476x_core *core = codec->control_data; | 68 | struct si476x_core *core = codec->control_data; |
49 | 69 | ||
50 | si476x_core_lock(core); | 70 | si476x_core_lock(core); |
51 | err = si476x_core_cmd_get_property(core, reg); | 71 | if (!si476x_core_is_powered_up(core)) |
72 | regcache_cache_only(core->regmap, true); | ||
73 | |||
74 | err = regmap_read(core->regmap, reg, &val); | ||
75 | |||
76 | if (!si476x_core_is_powered_up(core)) | ||
77 | regcache_cache_only(core->regmap, false); | ||
52 | si476x_core_unlock(core); | 78 | si476x_core_unlock(core); |
53 | 79 | ||
54 | return err; | 80 | if (err < 0) |
81 | return err; | ||
82 | |||
83 | return val; | ||
55 | } | 84 | } |
56 | 85 | ||
57 | static int si476x_codec_write(struct snd_soc_codec *codec, | 86 | static int si476x_codec_write(struct snd_soc_codec *codec, |
@@ -61,7 +90,13 @@ static int si476x_codec_write(struct snd_soc_codec *codec, | |||
61 | struct si476x_core *core = codec->control_data; | 90 | struct si476x_core *core = codec->control_data; |
62 | 91 | ||
63 | si476x_core_lock(core); | 92 | si476x_core_lock(core); |
64 | err = si476x_core_cmd_set_property(core, reg, val); | 93 | if (!si476x_core_is_powered_up(core)) |
94 | regcache_cache_only(core->regmap, true); | ||
95 | |||
96 | err = regmap_write(core->regmap, reg, val); | ||
97 | |||
98 | if (!si476x_core_is_powered_up(core)) | ||
99 | regcache_cache_only(core->regmap, false); | ||
65 | si476x_core_unlock(core); | 100 | si476x_core_unlock(core); |
66 | 101 | ||
67 | return err; | 102 | return err; |
@@ -140,7 +175,7 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
140 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); | 175 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); |
141 | return err; | 176 | return err; |
142 | } | 177 | } |
143 | 178 | ||
144 | return 0; | 179 | return 0; |
145 | } | 180 | } |
146 | 181 | ||
@@ -182,7 +217,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream, | |||
182 | 217 | ||
183 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | 218 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, |
184 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, | 219 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, |
185 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | | 220 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | |
186 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); | 221 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); |
187 | if (err < 0) { | 222 | if (err < 0) { |
188 | dev_err(dai->codec->dev, "Failed to set output width\n"); | 223 | dev_err(dai->codec->dev, "Failed to set output width\n"); |
@@ -251,6 +286,6 @@ static struct platform_driver si476x_platform_driver = { | |||
251 | }; | 286 | }; |
252 | module_platform_driver(si476x_platform_driver); | 287 | module_platform_driver(si476x_platform_driver); |
253 | 288 | ||
254 | MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); | 289 | MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>"); |
255 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); | 290 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); |
256 | MODULE_LICENSE("GPL"); | 291 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c new file mode 100644 index 000000000000..d447c4aa1d5e --- /dev/null +++ b/sound/soc/codecs/tas5086.c | |||
@@ -0,0 +1,591 @@ | |||
1 | /* | ||
2 | * TAS5086 ASoC codec driver | ||
3 | * | ||
4 | * Copyright (c) 2013 Daniel Mack <zonque@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * TODO: | ||
17 | * - implement DAPM and input muxing | ||
18 | * - implement modulation limit | ||
19 | * - implement non-default PWM start | ||
20 | * | ||
21 | * Note that this chip has a very unusual register layout, specifically | ||
22 | * because the registers are of unequal size, and multi-byte registers | ||
23 | * require bulk writes to take effect. Regmap does not support that kind | ||
24 | * of devices. | ||
25 | * | ||
26 | * Currently, the driver does not touch any of the registers >= 0x20, so | ||
27 | * it doesn't matter because the entire map can be accessed as 8-bit | ||
28 | * array. In case more features will be added in the future | ||
29 | * that require access to higher registers, the entire regmap H/W I/O | ||
30 | * routines have to be open-coded. | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/gpio.h> | ||
37 | #include <linux/i2c.h> | ||
38 | #include <linux/regmap.h> | ||
39 | #include <linux/spi/spi.h> | ||
40 | #include <linux/of_device.h> | ||
41 | #include <linux/of_gpio.h> | ||
42 | #include <sound/pcm.h> | ||
43 | #include <sound/pcm_params.h> | ||
44 | #include <sound/soc.h> | ||
45 | #include <sound/tlv.h> | ||
46 | #include <sound/tas5086.h> | ||
47 | |||
48 | #define TAS5086_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
49 | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
50 | SNDRV_PCM_FMTBIT_S24_3LE) | ||
51 | |||
52 | #define TAS5086_PCM_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ | ||
53 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \ | ||
54 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ | ||
55 | SNDRV_PCM_RATE_192000) | ||
56 | |||
57 | /* | ||
58 | * TAS5086 registers | ||
59 | */ | ||
60 | #define TAS5086_CLOCK_CONTROL 0x00 /* Clock control register */ | ||
61 | #define TAS5086_CLOCK_RATE(val) (val << 5) | ||
62 | #define TAS5086_CLOCK_RATE_MASK (0x7 << 5) | ||
63 | #define TAS5086_CLOCK_RATIO(val) (val << 2) | ||
64 | #define TAS5086_CLOCK_RATIO_MASK (0x7 << 2) | ||
65 | #define TAS5086_CLOCK_SCLK_RATIO_48 (1 << 1) | ||
66 | #define TAS5086_CLOCK_VALID (1 << 0) | ||
67 | |||
68 | #define TAS5086_DEEMPH_MASK 0x03 | ||
69 | #define TAS5086_SOFT_MUTE_ALL 0x3f | ||
70 | |||
71 | #define TAS5086_DEV_ID 0x01 /* Device ID register */ | ||
72 | #define TAS5086_ERROR_STATUS 0x02 /* Error status register */ | ||
73 | #define TAS5086_SYS_CONTROL_1 0x03 /* System control register 1 */ | ||
74 | #define TAS5086_SERIAL_DATA_IF 0x04 /* Serial data interface register */ | ||
75 | #define TAS5086_SYS_CONTROL_2 0x05 /* System control register 2 */ | ||
76 | #define TAS5086_SOFT_MUTE 0x06 /* Soft mute register */ | ||
77 | #define TAS5086_MASTER_VOL 0x07 /* Master volume */ | ||
78 | #define TAS5086_CHANNEL_VOL(X) (0x08 + (X)) /* Channel 1-6 volume */ | ||
79 | #define TAS5086_VOLUME_CONTROL 0x09 /* Volume control register */ | ||
80 | #define TAS5086_MOD_LIMIT 0x10 /* Modulation limit register */ | ||
81 | #define TAS5086_PWM_START 0x18 /* PWM start register */ | ||
82 | #define TAS5086_SURROUND 0x19 /* Surround register */ | ||
83 | #define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ | ||
84 | #define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ | ||
85 | #define TAS5086_BKNDERR 0x1c | ||
86 | |||
87 | /* | ||
88 | * Default TAS5086 power-up configuration | ||
89 | */ | ||
90 | static const struct reg_default tas5086_reg_defaults[] = { | ||
91 | { 0x00, 0x6c }, | ||
92 | { 0x01, 0x03 }, | ||
93 | { 0x02, 0x00 }, | ||
94 | { 0x03, 0xa0 }, | ||
95 | { 0x04, 0x05 }, | ||
96 | { 0x05, 0x60 }, | ||
97 | { 0x06, 0x00 }, | ||
98 | { 0x07, 0xff }, | ||
99 | { 0x08, 0x30 }, | ||
100 | { 0x09, 0x30 }, | ||
101 | { 0x0a, 0x30 }, | ||
102 | { 0x0b, 0x30 }, | ||
103 | { 0x0c, 0x30 }, | ||
104 | { 0x0d, 0x30 }, | ||
105 | { 0x0e, 0xb1 }, | ||
106 | { 0x0f, 0x00 }, | ||
107 | { 0x10, 0x02 }, | ||
108 | { 0x11, 0x00 }, | ||
109 | { 0x12, 0x00 }, | ||
110 | { 0x13, 0x00 }, | ||
111 | { 0x14, 0x00 }, | ||
112 | { 0x15, 0x00 }, | ||
113 | { 0x16, 0x00 }, | ||
114 | { 0x17, 0x00 }, | ||
115 | { 0x18, 0x3f }, | ||
116 | { 0x19, 0x00 }, | ||
117 | { 0x1a, 0x18 }, | ||
118 | { 0x1b, 0x82 }, | ||
119 | { 0x1c, 0x05 }, | ||
120 | }; | ||
121 | |||
122 | static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) | ||
123 | { | ||
124 | return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); | ||
125 | } | ||
126 | |||
127 | static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) | ||
128 | { | ||
129 | switch (reg) { | ||
130 | case TAS5086_DEV_ID: | ||
131 | case TAS5086_ERROR_STATUS: | ||
132 | return true; | ||
133 | } | ||
134 | |||
135 | return false; | ||
136 | } | ||
137 | |||
138 | static bool tas5086_writeable_reg(struct device *dev, unsigned int reg) | ||
139 | { | ||
140 | return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); | ||
141 | } | ||
142 | |||
143 | struct tas5086_private { | ||
144 | struct regmap *regmap; | ||
145 | unsigned int mclk, sclk; | ||
146 | unsigned int format; | ||
147 | bool deemph; | ||
148 | /* Current sample rate for de-emphasis control */ | ||
149 | int rate; | ||
150 | /* GPIO driving Reset pin, if any */ | ||
151 | int gpio_nreset; | ||
152 | }; | ||
153 | |||
154 | static int tas5086_deemph[] = { 0, 32000, 44100, 48000 }; | ||
155 | |||
156 | static int tas5086_set_deemph(struct snd_soc_codec *codec) | ||
157 | { | ||
158 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
159 | int i, val = 0; | ||
160 | |||
161 | if (priv->deemph) | ||
162 | for (i = 0; i < ARRAY_SIZE(tas5086_deemph); i++) | ||
163 | if (tas5086_deemph[i] == priv->rate) | ||
164 | val = i; | ||
165 | |||
166 | return regmap_update_bits(priv->regmap, TAS5086_SYS_CONTROL_1, | ||
167 | TAS5086_DEEMPH_MASK, val); | ||
168 | } | ||
169 | |||
170 | static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, | ||
171 | struct snd_ctl_elem_value *ucontrol) | ||
172 | { | ||
173 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
174 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
175 | |||
176 | ucontrol->value.enumerated.item[0] = priv->deemph; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, | ||
182 | struct snd_ctl_elem_value *ucontrol) | ||
183 | { | ||
184 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
185 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
186 | |||
187 | priv->deemph = ucontrol->value.enumerated.item[0]; | ||
188 | |||
189 | return tas5086_set_deemph(codec); | ||
190 | } | ||
191 | |||
192 | |||
193 | static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
194 | int clk_id, unsigned int freq, int dir) | ||
195 | { | ||
196 | struct snd_soc_codec *codec = codec_dai->codec; | ||
197 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
198 | |||
199 | switch (clk_id) { | ||
200 | case TAS5086_CLK_IDX_MCLK: | ||
201 | priv->mclk = freq; | ||
202 | break; | ||
203 | case TAS5086_CLK_IDX_SCLK: | ||
204 | priv->sclk = freq; | ||
205 | break; | ||
206 | } | ||
207 | |||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
212 | unsigned int format) | ||
213 | { | ||
214 | struct snd_soc_codec *codec = codec_dai->codec; | ||
215 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
216 | |||
217 | /* The TAS5086 can only be slave to all clocks */ | ||
218 | if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { | ||
219 | dev_err(codec->dev, "Invalid clocking mode\n"); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | /* we need to refer to the data format from hw_params() */ | ||
224 | priv->format = format; | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static const int tas5086_sample_rates[] = { | ||
230 | 32000, 38000, 44100, 48000, 88200, 96000, 176400, 192000 | ||
231 | }; | ||
232 | |||
233 | static const int tas5086_ratios[] = { | ||
234 | 64, 128, 192, 256, 384, 512 | ||
235 | }; | ||
236 | |||
237 | static int index_in_array(const int *array, int len, int needle) | ||
238 | { | ||
239 | int i; | ||
240 | |||
241 | for (i = 0; i < len; i++) | ||
242 | if (array[i] == needle) | ||
243 | return i; | ||
244 | |||
245 | return -ENOENT; | ||
246 | } | ||
247 | |||
248 | static int tas5086_hw_params(struct snd_pcm_substream *substream, | ||
249 | struct snd_pcm_hw_params *params, | ||
250 | struct snd_soc_dai *dai) | ||
251 | { | ||
252 | struct snd_soc_codec *codec = dai->codec; | ||
253 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
254 | int val; | ||
255 | int ret; | ||
256 | |||
257 | priv->rate = params_rate(params); | ||
258 | |||
259 | /* Look up the sample rate and refer to the offset in the list */ | ||
260 | val = index_in_array(tas5086_sample_rates, | ||
261 | ARRAY_SIZE(tas5086_sample_rates), priv->rate); | ||
262 | |||
263 | if (val < 0) { | ||
264 | dev_err(codec->dev, "Invalid sample rate\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, | ||
269 | TAS5086_CLOCK_RATE_MASK, | ||
270 | TAS5086_CLOCK_RATE(val)); | ||
271 | if (ret < 0) | ||
272 | return ret; | ||
273 | |||
274 | /* MCLK / Fs ratio */ | ||
275 | val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), | ||
276 | priv->mclk / priv->rate); | ||
277 | if (val < 0) { | ||
278 | dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n"); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | |||
282 | ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, | ||
283 | TAS5086_CLOCK_RATIO_MASK, | ||
284 | TAS5086_CLOCK_RATIO(val)); | ||
285 | if (ret < 0) | ||
286 | return ret; | ||
287 | |||
288 | |||
289 | ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, | ||
290 | TAS5086_CLOCK_SCLK_RATIO_48, | ||
291 | (priv->sclk == 48 * priv->rate) ? | ||
292 | TAS5086_CLOCK_SCLK_RATIO_48 : 0); | ||
293 | if (ret < 0) | ||
294 | return ret; | ||
295 | |||
296 | /* | ||
297 | * The chip has a very unituitive register mapping and muxes information | ||
298 | * about data format and sample depth into the same register, but not on | ||
299 | * a logical bit-boundary. Hence, we have to refer to the format passed | ||
300 | * in the set_dai_fmt() callback and set up everything from here. | ||
301 | * | ||
302 | * First, determine the 'base' value, using the format ... | ||
303 | */ | ||
304 | switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
305 | case SND_SOC_DAIFMT_RIGHT_J: | ||
306 | val = 0x00; | ||
307 | break; | ||
308 | case SND_SOC_DAIFMT_I2S: | ||
309 | val = 0x03; | ||
310 | break; | ||
311 | case SND_SOC_DAIFMT_LEFT_J: | ||
312 | val = 0x06; | ||
313 | break; | ||
314 | default: | ||
315 | dev_err(codec->dev, "Invalid DAI format\n"); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | /* ... then add the offset for the sample bit depth. */ | ||
320 | switch (params_format(params)) { | ||
321 | case SNDRV_PCM_FORMAT_S16_LE: | ||
322 | val += 0; | ||
323 | break; | ||
324 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
325 | val += 1; | ||
326 | break; | ||
327 | case SNDRV_PCM_FORMAT_S24_3LE: | ||
328 | val += 2; | ||
329 | break; | ||
330 | default: | ||
331 | dev_err(codec->dev, "Invalid bit width\n"); | ||
332 | return -EINVAL; | ||
333 | }; | ||
334 | |||
335 | ret = regmap_write(priv->regmap, TAS5086_SERIAL_DATA_IF, val); | ||
336 | if (ret < 0) | ||
337 | return ret; | ||
338 | |||
339 | /* clock is considered valid now */ | ||
340 | ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, | ||
341 | TAS5086_CLOCK_VALID, TAS5086_CLOCK_VALID); | ||
342 | if (ret < 0) | ||
343 | return ret; | ||
344 | |||
345 | return tas5086_set_deemph(codec); | ||
346 | } | ||
347 | |||
348 | static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream) | ||
349 | { | ||
350 | struct snd_soc_codec *codec = dai->codec; | ||
351 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
352 | unsigned int val = 0; | ||
353 | |||
354 | if (mute) | ||
355 | val = TAS5086_SOFT_MUTE_ALL; | ||
356 | |||
357 | return regmap_write(priv->regmap, TAS5086_SOFT_MUTE, val); | ||
358 | } | ||
359 | |||
360 | /* TAS5086 controls */ | ||
361 | static const DECLARE_TLV_DB_SCALE(tas5086_dac_tlv, -10350, 50, 1); | ||
362 | |||
363 | static const struct snd_kcontrol_new tas5086_controls[] = { | ||
364 | SOC_SINGLE_TLV("Master Playback Volume", TAS5086_MASTER_VOL, | ||
365 | 0, 0xff, 1, tas5086_dac_tlv), | ||
366 | SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume", | ||
367 | TAS5086_CHANNEL_VOL(0), TAS5086_CHANNEL_VOL(1), | ||
368 | 0, 0xff, 1, tas5086_dac_tlv), | ||
369 | SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume", | ||
370 | TAS5086_CHANNEL_VOL(2), TAS5086_CHANNEL_VOL(3), | ||
371 | 0, 0xff, 1, tas5086_dac_tlv), | ||
372 | SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume", | ||
373 | TAS5086_CHANNEL_VOL(4), TAS5086_CHANNEL_VOL(5), | ||
374 | 0, 0xff, 1, tas5086_dac_tlv), | ||
375 | SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0, | ||
376 | tas5086_get_deemph, tas5086_put_deemph), | ||
377 | }; | ||
378 | |||
379 | static const struct snd_soc_dai_ops tas5086_dai_ops = { | ||
380 | .hw_params = tas5086_hw_params, | ||
381 | .set_sysclk = tas5086_set_dai_sysclk, | ||
382 | .set_fmt = tas5086_set_dai_fmt, | ||
383 | .mute_stream = tas5086_mute_stream, | ||
384 | }; | ||
385 | |||
386 | static struct snd_soc_dai_driver tas5086_dai = { | ||
387 | .name = "tas5086-hifi", | ||
388 | .playback = { | ||
389 | .stream_name = "Playback", | ||
390 | .channels_min = 2, | ||
391 | .channels_max = 6, | ||
392 | .rates = TAS5086_PCM_RATES, | ||
393 | .formats = TAS5086_PCM_FORMATS, | ||
394 | }, | ||
395 | .ops = &tas5086_dai_ops, | ||
396 | }; | ||
397 | |||
398 | #ifdef CONFIG_PM | ||
399 | static int tas5086_soc_resume(struct snd_soc_codec *codec) | ||
400 | { | ||
401 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
402 | |||
403 | /* Restore codec state */ | ||
404 | return regcache_sync(priv->regmap); | ||
405 | } | ||
406 | #else | ||
407 | #define tas5086_soc_resume NULL | ||
408 | #endif /* CONFIG_PM */ | ||
409 | |||
410 | #ifdef CONFIG_OF | ||
411 | static const struct of_device_id tas5086_dt_ids[] = { | ||
412 | { .compatible = "ti,tas5086", }, | ||
413 | { } | ||
414 | }; | ||
415 | MODULE_DEVICE_TABLE(of, tas5086_dt_ids); | ||
416 | #endif | ||
417 | |||
418 | /* charge period values in microseconds */ | ||
419 | static const int tas5086_charge_period[] = { | ||
420 | 13000, 16900, 23400, 31200, 41600, 54600, 72800, 96200, | ||
421 | 130000, 156000, 234000, 312000, 416000, 546000, 728000, 962000, | ||
422 | 1300000, 169000, 2340000, 3120000, 4160000, 5460000, 7280000, 9620000, | ||
423 | }; | ||
424 | |||
425 | static int tas5086_probe(struct snd_soc_codec *codec) | ||
426 | { | ||
427 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
428 | int charge_period = 1300000; /* hardware default is 1300 ms */ | ||
429 | int i, ret; | ||
430 | |||
431 | if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { | ||
432 | struct device_node *of_node = codec->dev->of_node; | ||
433 | of_property_read_u32(of_node, "ti,charge-period", &charge_period); | ||
434 | } | ||
435 | |||
436 | /* lookup and set split-capacitor charge period */ | ||
437 | if (charge_period == 0) { | ||
438 | regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); | ||
439 | } else { | ||
440 | i = index_in_array(tas5086_charge_period, | ||
441 | ARRAY_SIZE(tas5086_charge_period), | ||
442 | charge_period); | ||
443 | if (i >= 0) | ||
444 | regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, | ||
445 | i + 0x08); | ||
446 | else | ||
447 | dev_warn(codec->dev, | ||
448 | "Invalid split-cap charge period of %d ns.\n", | ||
449 | charge_period); | ||
450 | } | ||
451 | |||
452 | /* enable factory trim */ | ||
453 | ret = regmap_write(priv->regmap, TAS5086_OSC_TRIM, 0x00); | ||
454 | if (ret < 0) | ||
455 | return ret; | ||
456 | |||
457 | /* start all channels */ | ||
458 | ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x20); | ||
459 | if (ret < 0) | ||
460 | return ret; | ||
461 | |||
462 | /* set master volume to 0 dB */ | ||
463 | ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30); | ||
464 | if (ret < 0) | ||
465 | return ret; | ||
466 | |||
467 | /* mute all channels for now */ | ||
468 | ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE, | ||
469 | TAS5086_SOFT_MUTE_ALL); | ||
470 | if (ret < 0) | ||
471 | return ret; | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int tas5086_remove(struct snd_soc_codec *codec) | ||
477 | { | ||
478 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | ||
479 | |||
480 | if (gpio_is_valid(priv->gpio_nreset)) | ||
481 | /* Set codec to the reset state */ | ||
482 | gpio_set_value(priv->gpio_nreset, 0); | ||
483 | |||
484 | return 0; | ||
485 | }; | ||
486 | |||
487 | static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { | ||
488 | .probe = tas5086_probe, | ||
489 | .remove = tas5086_remove, | ||
490 | .resume = tas5086_soc_resume, | ||
491 | .controls = tas5086_controls, | ||
492 | .num_controls = ARRAY_SIZE(tas5086_controls), | ||
493 | }; | ||
494 | |||
495 | static const struct i2c_device_id tas5086_i2c_id[] = { | ||
496 | { "tas5086", 0 }, | ||
497 | { } | ||
498 | }; | ||
499 | MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id); | ||
500 | |||
501 | static const struct regmap_config tas5086_regmap = { | ||
502 | .reg_bits = 8, | ||
503 | .val_bits = 8, | ||
504 | .max_register = ARRAY_SIZE(tas5086_reg_defaults), | ||
505 | .reg_defaults = tas5086_reg_defaults, | ||
506 | .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), | ||
507 | .cache_type = REGCACHE_RBTREE, | ||
508 | .volatile_reg = tas5086_volatile_reg, | ||
509 | .writeable_reg = tas5086_writeable_reg, | ||
510 | .readable_reg = tas5086_accessible_reg, | ||
511 | }; | ||
512 | |||
513 | static int tas5086_i2c_probe(struct i2c_client *i2c, | ||
514 | const struct i2c_device_id *id) | ||
515 | { | ||
516 | struct tas5086_private *priv; | ||
517 | struct device *dev = &i2c->dev; | ||
518 | int gpio_nreset = -EINVAL; | ||
519 | int i, ret; | ||
520 | |||
521 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
522 | if (!priv) | ||
523 | return -ENOMEM; | ||
524 | |||
525 | priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); | ||
526 | if (IS_ERR(priv->regmap)) { | ||
527 | ret = PTR_ERR(priv->regmap); | ||
528 | dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); | ||
529 | return ret; | ||
530 | } | ||
531 | |||
532 | i2c_set_clientdata(i2c, priv); | ||
533 | |||
534 | if (of_match_device(of_match_ptr(tas5086_dt_ids), dev)) { | ||
535 | struct device_node *of_node = dev->of_node; | ||
536 | gpio_nreset = of_get_named_gpio(of_node, "reset-gpio", 0); | ||
537 | } | ||
538 | |||
539 | if (gpio_is_valid(gpio_nreset)) | ||
540 | if (devm_gpio_request(dev, gpio_nreset, "TAS5086 Reset")) | ||
541 | gpio_nreset = -EINVAL; | ||
542 | |||
543 | if (gpio_is_valid(gpio_nreset)) { | ||
544 | /* Reset codec - minimum assertion time is 400ns */ | ||
545 | gpio_direction_output(gpio_nreset, 0); | ||
546 | udelay(1); | ||
547 | gpio_set_value(gpio_nreset, 1); | ||
548 | |||
549 | /* Codec needs ~15ms to wake up */ | ||
550 | msleep(15); | ||
551 | } | ||
552 | |||
553 | priv->gpio_nreset = gpio_nreset; | ||
554 | |||
555 | /* The TAS5086 always returns 0x03 in its TAS5086_DEV_ID register */ | ||
556 | ret = regmap_read(priv->regmap, TAS5086_DEV_ID, &i); | ||
557 | if (ret < 0) | ||
558 | return ret; | ||
559 | |||
560 | if (i != 0x3) { | ||
561 | dev_err(dev, | ||
562 | "Failed to identify TAS5086 codec (got %02x)\n", i); | ||
563 | return -ENODEV; | ||
564 | } | ||
565 | |||
566 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tas5086, | ||
567 | &tas5086_dai, 1); | ||
568 | } | ||
569 | |||
570 | static int tas5086_i2c_remove(struct i2c_client *i2c) | ||
571 | { | ||
572 | snd_soc_unregister_codec(&i2c->dev); | ||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static struct i2c_driver tas5086_i2c_driver = { | ||
577 | .driver = { | ||
578 | .name = "tas5086", | ||
579 | .owner = THIS_MODULE, | ||
580 | .of_match_table = of_match_ptr(tas5086_dt_ids), | ||
581 | }, | ||
582 | .id_table = tas5086_i2c_id, | ||
583 | .probe = tas5086_i2c_probe, | ||
584 | .remove = tas5086_i2c_remove, | ||
585 | }; | ||
586 | |||
587 | module_i2c_driver(tas5086_i2c_driver); | ||
588 | |||
589 | MODULE_AUTHOR("Daniel Mack <zonque@gmail.com>"); | ||
590 | MODULE_DESCRIPTION("Texas Instruments TAS5086 ALSA SoC Codec Driver"); | ||
591 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index ad2fee4bb4cd..8df2b6e1a1a6 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -342,7 +342,7 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) | |||
342 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); | 342 | data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); |
343 | } | 343 | } |
344 | 344 | ||
345 | static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) | 345 | static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec) |
346 | { | 346 | { |
347 | struct spi_device *spi = to_spi_device(codec->dev); | 347 | struct spi_device *spi = to_spi_device(codec->dev); |
348 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); | 348 | struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); |
@@ -361,8 +361,8 @@ static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) | |||
361 | 361 | ||
362 | ret = request_firmware(&fw, name, codec->dev); | 362 | ret = request_firmware(&fw, name, codec->dev); |
363 | if (ret != 0) { | 363 | if (ret != 0) { |
364 | dev_err(codec->dev, "Failed to request application: %d\n", | 364 | dev_err(codec->dev, "Failed to request application(%s): %d\n", |
365 | ret); | 365 | name, ret); |
366 | return ret; | 366 | return ret; |
367 | } | 367 | } |
368 | 368 | ||
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index f2ac38b61a1b..7fefd766b582 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -761,6 +761,8 @@ static bool wm2000_readable_reg(struct device *dev, unsigned int reg) | |||
761 | case WM2000_REG_SYS_CTL2: | 761 | case WM2000_REG_SYS_CTL2: |
762 | case WM2000_REG_ANC_STAT: | 762 | case WM2000_REG_ANC_STAT: |
763 | case WM2000_REG_IF_CTL: | 763 | case WM2000_REG_IF_CTL: |
764 | case WM2000_REG_ANA_MIC_CTL: | ||
765 | case WM2000_REG_SPK_CTL: | ||
764 | return true; | 766 | return true; |
765 | default: | 767 | default: |
766 | return false; | 768 | return false; |
@@ -771,7 +773,7 @@ static const struct regmap_config wm2000_regmap = { | |||
771 | .reg_bits = 16, | 773 | .reg_bits = 16, |
772 | .val_bits = 8, | 774 | .val_bits = 8, |
773 | 775 | ||
774 | .max_register = WM2000_REG_IF_CTL, | 776 | .max_register = WM2000_REG_SPK_CTL, |
775 | .readable_reg = wm2000_readable_reg, | 777 | .readable_reg = wm2000_readable_reg, |
776 | }; | 778 | }; |
777 | 779 | ||
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h index fb812cd9e77d..3870c0e1d246 100644 --- a/sound/soc/codecs/wm2000.h +++ b/sound/soc/codecs/wm2000.h | |||
@@ -30,6 +30,8 @@ | |||
30 | #define WM2000_REG_SYS_CTL2 0xf004 | 30 | #define WM2000_REG_SYS_CTL2 0xf004 |
31 | #define WM2000_REG_ANC_STAT 0xf005 | 31 | #define WM2000_REG_ANC_STAT 0xf005 |
32 | #define WM2000_REG_IF_CTL 0xf006 | 32 | #define WM2000_REG_IF_CTL 0xf006 |
33 | #define WM2000_REG_ANA_MIC_CTL 0xf028 | ||
34 | #define WM2000_REG_SPK_CTL 0xf034 | ||
33 | 35 | ||
34 | /* SPEECH_CLARITY */ | 36 | /* SPEECH_CLARITY */ |
35 | #define WM2000_SPEECH_CLARITY 0x01 | 37 | #define WM2000_SPEECH_CLARITY 0x01 |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index ddc98f02ecbd..57ba315d0c84 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec) | |||
1565 | return ret; | 1565 | return ret; |
1566 | } | 1566 | } |
1567 | 1567 | ||
1568 | ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); | 1568 | ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); |
1569 | if (ret != 0) | 1569 | if (ret != 0) |
1570 | return ret; | 1570 | return ret; |
1571 | 1571 | ||
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 15bc31f1abb1..e895d3939eef 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -36,9 +36,6 @@ | |||
36 | struct wm5102_priv { | 36 | struct wm5102_priv { |
37 | struct arizona_priv core; | 37 | struct arizona_priv core; |
38 | struct arizona_fll fll[2]; | 38 | struct arizona_fll fll[2]; |
39 | |||
40 | unsigned int spk_ena:2; | ||
41 | unsigned int spk_ena_pending:1; | ||
42 | }; | 39 | }; |
43 | 40 | ||
44 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); | 41 | static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); |
@@ -615,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
615 | return 0; | 612 | return 0; |
616 | } | 613 | } |
617 | 614 | ||
615 | static const char *wm5102_osr_text[] = { | ||
616 | "Low power", "Normal", "High performance", | ||
617 | }; | ||
618 | |||
619 | static const unsigned int wm5102_osr_val[] = { | ||
620 | 0x0, 0x3, 0x5, | ||
621 | }; | ||
622 | |||
623 | static const struct soc_enum wm5102_hpout_osr[] = { | ||
624 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, | ||
625 | ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, | ||
626 | wm5102_osr_text, wm5102_osr_val), | ||
627 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, | ||
628 | ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, | ||
629 | wm5102_osr_text, wm5102_osr_val), | ||
630 | SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, | ||
631 | ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, | ||
632 | wm5102_osr_text, wm5102_osr_val), | ||
633 | }; | ||
634 | |||
618 | #define WM5102_NG_SRC(name, base) \ | 635 | #define WM5102_NG_SRC(name, base) \ |
619 | SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ | 636 | SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ |
620 | SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ | 637 | SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ |
@@ -745,6 +762,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
745 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 762 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
746 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 763 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
747 | 764 | ||
765 | SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | ||
766 | SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | ||
767 | |||
748 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 768 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
749 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 769 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
750 | 770 | ||
@@ -761,6 +781,8 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), | |||
761 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), | 781 | ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), |
762 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), | 782 | ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), |
763 | 783 | ||
784 | SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, | ||
785 | ARIZONA_OUT4_OSR_SHIFT, 1, 0), | ||
764 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, | 786 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, |
765 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), | 787 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), |
766 | 788 | ||
@@ -790,6 +812,10 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
790 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 812 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
791 | 0xbf, 0, digital_tlv), | 813 | 0xbf, 0, digital_tlv), |
792 | 814 | ||
815 | SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), | ||
816 | SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), | ||
817 | SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]), | ||
818 | |||
793 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), | 819 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), |
794 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), | 820 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), |
795 | 821 | ||
@@ -828,47 +854,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), | |||
828 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), | 854 | ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), |
829 | }; | 855 | }; |
830 | 856 | ||
831 | static int wm5102_spk_ev(struct snd_soc_dapm_widget *w, | ||
832 | struct snd_kcontrol *kcontrol, | ||
833 | int event) | ||
834 | { | ||
835 | struct snd_soc_codec *codec = w->codec; | ||
836 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | ||
837 | struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); | ||
838 | |||
839 | if (arizona->rev < 1) | ||
840 | return 0; | ||
841 | |||
842 | switch (event) { | ||
843 | case SND_SOC_DAPM_PRE_PMU: | ||
844 | if (!wm5102->spk_ena) { | ||
845 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
846 | wm5102->spk_ena_pending = true; | ||
847 | } | ||
848 | break; | ||
849 | case SND_SOC_DAPM_POST_PMU: | ||
850 | if (wm5102->spk_ena_pending) { | ||
851 | msleep(75); | ||
852 | snd_soc_write(codec, 0x4f5, 0xda); | ||
853 | wm5102->spk_ena_pending = false; | ||
854 | wm5102->spk_ena++; | ||
855 | } | ||
856 | break; | ||
857 | case SND_SOC_DAPM_PRE_PMD: | ||
858 | wm5102->spk_ena--; | ||
859 | if (!wm5102->spk_ena) | ||
860 | snd_soc_write(codec, 0x4f5, 0x25a); | ||
861 | break; | ||
862 | case SND_SOC_DAPM_POST_PMD: | ||
863 | if (!wm5102->spk_ena) | ||
864 | snd_soc_write(codec, 0x4f5, 0x0da); | ||
865 | break; | ||
866 | } | ||
867 | |||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | |||
872 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); | 857 | ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); |
873 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); | 858 | ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); |
874 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); | 859 | ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); |
@@ -984,22 +969,28 @@ SND_SOC_DAPM_INPUT("IN3R"), | |||
984 | 969 | ||
985 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 970 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, |
986 | 0, NULL, 0, arizona_in_ev, | 971 | 0, NULL, 0, arizona_in_ev, |
987 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 972 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
973 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
988 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 974 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, |
989 | 0, NULL, 0, arizona_in_ev, | 975 | 0, NULL, 0, arizona_in_ev, |
990 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 976 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
977 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
991 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 978 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, |
992 | 0, NULL, 0, arizona_in_ev, | 979 | 0, NULL, 0, arizona_in_ev, |
993 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 980 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
981 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
994 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 982 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, |
995 | 0, NULL, 0, arizona_in_ev, | 983 | 0, NULL, 0, arizona_in_ev, |
996 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 984 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
985 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
997 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 986 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, |
998 | 0, NULL, 0, arizona_in_ev, | 987 | 0, NULL, 0, arizona_in_ev, |
999 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 988 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
989 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1000 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 990 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, |
1001 | 0, NULL, 0, arizona_in_ev, | 991 | 0, NULL, 0, arizona_in_ev, |
1002 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 992 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
993 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
1003 | 994 | ||
1004 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 995 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
1005 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 996 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
@@ -1146,12 +1137,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, | |||
1146 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | 1137 | SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, |
1147 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1138 | ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1148 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1139 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
1149 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, | ||
1150 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, | ||
1151 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1152 | SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, | ||
1153 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, | ||
1154 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1155 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 1140 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
1156 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 1141 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
1157 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 1142 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
@@ -1494,6 +1479,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
1494 | return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); | 1479 | return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); |
1495 | case WM5102_FLL2: | 1480 | case WM5102_FLL2: |
1496 | return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); | 1481 | return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); |
1482 | case WM5102_FLL1_REFCLK: | ||
1483 | return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref, | ||
1484 | Fout); | ||
1485 | case WM5102_FLL2_REFCLK: | ||
1486 | return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref, | ||
1487 | Fout); | ||
1497 | default: | 1488 | default: |
1498 | return -EINVAL; | 1489 | return -EINVAL; |
1499 | } | 1490 | } |
@@ -1581,10 +1572,12 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
1581 | if (ret != 0) | 1572 | if (ret != 0) |
1582 | return ret; | 1573 | return ret; |
1583 | 1574 | ||
1584 | ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); | 1575 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); |
1585 | if (ret != 0) | 1576 | if (ret != 0) |
1586 | return ret; | 1577 | return ret; |
1587 | 1578 | ||
1579 | arizona_init_spk(codec); | ||
1580 | |||
1588 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); | 1581 | snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); |
1589 | 1582 | ||
1590 | priv->core.arizona->dapm = &codec->dapm; | 1583 | priv->core.arizona->dapm = &codec->dapm; |
@@ -1604,13 +1597,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec) | |||
1604 | #define WM5102_DIG_VU 0x0200 | 1597 | #define WM5102_DIG_VU 0x0200 |
1605 | 1598 | ||
1606 | static unsigned int wm5102_digital_vu[] = { | 1599 | static unsigned int wm5102_digital_vu[] = { |
1607 | ARIZONA_ADC_DIGITAL_VOLUME_1L, | ||
1608 | ARIZONA_ADC_DIGITAL_VOLUME_1R, | ||
1609 | ARIZONA_ADC_DIGITAL_VOLUME_2L, | ||
1610 | ARIZONA_ADC_DIGITAL_VOLUME_2R, | ||
1611 | ARIZONA_ADC_DIGITAL_VOLUME_3L, | ||
1612 | ARIZONA_ADC_DIGITAL_VOLUME_3R, | ||
1613 | |||
1614 | ARIZONA_DAC_DIGITAL_VOLUME_1L, | 1600 | ARIZONA_DAC_DIGITAL_VOLUME_1L, |
1615 | ARIZONA_DAC_DIGITAL_VOLUME_1R, | 1601 | ARIZONA_DAC_DIGITAL_VOLUME_1R, |
1616 | ARIZONA_DAC_DIGITAL_VOLUME_2L, | 1602 | ARIZONA_DAC_DIGITAL_VOLUME_2L, |
@@ -1653,6 +1639,7 @@ static int wm5102_probe(struct platform_device *pdev) | |||
1653 | platform_set_drvdata(pdev, wm5102); | 1639 | platform_set_drvdata(pdev, wm5102); |
1654 | 1640 | ||
1655 | wm5102->core.arizona = arizona; | 1641 | wm5102->core.arizona = arizona; |
1642 | wm5102->core.num_inputs = 6; | ||
1656 | 1643 | ||
1657 | wm5102->core.adsp[0].part = "wm5102"; | 1644 | wm5102->core.adsp[0].part = "wm5102"; |
1658 | wm5102->core.adsp[0].num = 1; | 1645 | wm5102->core.adsp[0].num = 1; |
@@ -1677,6 +1664,12 @@ static int wm5102_probe(struct platform_device *pdev) | |||
1677 | ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, | 1664 | ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, |
1678 | &wm5102->fll[1]); | 1665 | &wm5102->fll[1]); |
1679 | 1666 | ||
1667 | /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */ | ||
1668 | regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2, | ||
1669 | ARIZONA_SAMPLE_RATE_2_MASK, 0x11); | ||
1670 | regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3, | ||
1671 | ARIZONA_SAMPLE_RATE_3_MASK, 0x12); | ||
1672 | |||
1680 | for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) | 1673 | for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) |
1681 | arizona_init_dai(&wm5102->core, i); | 1674 | arizona_init_dai(&wm5102->core, i); |
1682 | 1675 | ||
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h index d30477f3070c..adb38040f661 100644 --- a/sound/soc/codecs/wm5102.h +++ b/sound/soc/codecs/wm5102.h | |||
@@ -15,7 +15,9 @@ | |||
15 | 15 | ||
16 | #include "arizona.h" | 16 | #include "arizona.h" |
17 | 17 | ||
18 | #define WM5102_FLL1 1 | 18 | #define WM5102_FLL1 1 |
19 | #define WM5102_FLL2 2 | 19 | #define WM5102_FLL2 2 |
20 | #define WM5102_FLL1_REFCLK 3 | ||
21 | #define WM5102_FLL2_REFCLK 4 | ||
20 | 22 | ||
21 | #endif | 23 | #endif |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 7841b42a819c..731884e04776 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"), | |||
416 | 416 | ||
417 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, | 417 | SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, |
418 | 0, NULL, 0, arizona_in_ev, | 418 | 0, NULL, 0, arizona_in_ev, |
419 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 419 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
420 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
420 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, | 421 | SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, |
421 | 0, NULL, 0, arizona_in_ev, | 422 | 0, NULL, 0, arizona_in_ev, |
422 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 423 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
424 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
423 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, | 425 | SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, |
424 | 0, NULL, 0, arizona_in_ev, | 426 | 0, NULL, 0, arizona_in_ev, |
425 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 427 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
428 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
426 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, | 429 | SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, |
427 | 0, NULL, 0, arizona_in_ev, | 430 | 0, NULL, 0, arizona_in_ev, |
428 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 431 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
432 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
429 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, | 433 | SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, |
430 | 0, NULL, 0, arizona_in_ev, | 434 | 0, NULL, 0, arizona_in_ev, |
431 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 435 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
436 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
432 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, | 437 | SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, |
433 | 0, NULL, 0, arizona_in_ev, | 438 | 0, NULL, 0, arizona_in_ev, |
434 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 439 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
440 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
435 | SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, | 441 | SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, |
436 | 0, NULL, 0, arizona_in_ev, | 442 | 0, NULL, 0, arizona_in_ev, |
437 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 443 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
444 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
438 | SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, | 445 | SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, |
439 | 0, NULL, 0, arizona_in_ev, | 446 | 0, NULL, 0, arizona_in_ev, |
440 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 447 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | |
448 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), | ||
441 | 449 | ||
442 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, | 450 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, |
443 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), | 451 | ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), |
@@ -569,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, | |||
569 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, | 577 | SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, |
570 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 578 | ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
571 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 579 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
572 | SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, | ||
573 | ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | ||
574 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
575 | SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, | ||
576 | ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | ||
577 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
578 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, | 580 | SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, |
579 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, | 581 | ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, |
580 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | 582 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
@@ -880,6 +882,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
880 | return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); | 882 | return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); |
881 | case WM5110_FLL2: | 883 | case WM5110_FLL2: |
882 | return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); | 884 | return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); |
885 | case WM5110_FLL1_REFCLK: | ||
886 | return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref, | ||
887 | Fout); | ||
888 | case WM5110_FLL2_REFCLK: | ||
889 | return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref, | ||
890 | Fout); | ||
883 | default: | 891 | default: |
884 | return -EINVAL; | 892 | return -EINVAL; |
885 | } | 893 | } |
@@ -987,15 +995,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) | |||
987 | #define WM5110_DIG_VU 0x0200 | 995 | #define WM5110_DIG_VU 0x0200 |
988 | 996 | ||
989 | static unsigned int wm5110_digital_vu[] = { | 997 | static unsigned int wm5110_digital_vu[] = { |
990 | ARIZONA_ADC_DIGITAL_VOLUME_1L, | ||
991 | ARIZONA_ADC_DIGITAL_VOLUME_1R, | ||
992 | ARIZONA_ADC_DIGITAL_VOLUME_2L, | ||
993 | ARIZONA_ADC_DIGITAL_VOLUME_2R, | ||
994 | ARIZONA_ADC_DIGITAL_VOLUME_3L, | ||
995 | ARIZONA_ADC_DIGITAL_VOLUME_3R, | ||
996 | ARIZONA_ADC_DIGITAL_VOLUME_4L, | ||
997 | ARIZONA_ADC_DIGITAL_VOLUME_4R, | ||
998 | |||
999 | ARIZONA_DAC_DIGITAL_VOLUME_1L, | 998 | ARIZONA_DAC_DIGITAL_VOLUME_1L, |
1000 | ARIZONA_DAC_DIGITAL_VOLUME_1R, | 999 | ARIZONA_DAC_DIGITAL_VOLUME_1R, |
1001 | ARIZONA_DAC_DIGITAL_VOLUME_2L, | 1000 | ARIZONA_DAC_DIGITAL_VOLUME_2L, |
@@ -1040,6 +1039,7 @@ static int wm5110_probe(struct platform_device *pdev) | |||
1040 | platform_set_drvdata(pdev, wm5110); | 1039 | platform_set_drvdata(pdev, wm5110); |
1041 | 1040 | ||
1042 | wm5110->core.arizona = arizona; | 1041 | wm5110->core.arizona = arizona; |
1042 | wm5110->core.num_inputs = 8; | ||
1043 | 1043 | ||
1044 | for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) | 1044 | for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) |
1045 | wm5110->fll[i].vco_mult = 3; | 1045 | wm5110->fll[i].vco_mult = 3; |
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h index 75e9351ccab0..e6c0cd4235c5 100644 --- a/sound/soc/codecs/wm5110.h +++ b/sound/soc/codecs/wm5110.h | |||
@@ -15,7 +15,9 @@ | |||
15 | 15 | ||
16 | #include "arizona.h" | 16 | #include "arizona.h" |
17 | 17 | ||
18 | #define WM5110_FLL1 1 | 18 | #define WM5110_FLL1 1 |
19 | #define WM5110_FLL2 2 | 19 | #define WM5110_FLL2 2 |
20 | #define WM5110_FLL1_REFCLK 3 | ||
21 | #define WM5110_FLL2_REFCLK 4 | ||
20 | 22 | ||
21 | #endif | 23 | #endif |
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index f8a31ad0b203..9d88437cdcd1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -478,6 +478,8 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, | |||
478 | /* ALSA can only do steps of .01dB */ | 478 | /* ALSA can only do steps of .01dB */ |
479 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 479 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
480 | 480 | ||
481 | static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0); | ||
482 | |||
481 | static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); | 483 | static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); |
482 | static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); | 484 | static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); |
483 | 485 | ||
@@ -698,6 +700,8 @@ SOC_ENUM("DAC Mute Mode", mute_mode), | |||
698 | SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), | 700 | SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), |
699 | SOC_ENUM("DAC Companding Mode", dac_companding), | 701 | SOC_ENUM("DAC Companding Mode", dac_companding), |
700 | SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), | 702 | SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), |
703 | SOC_SINGLE_TLV("DAC Boost Volume", WM8903_AUDIO_INTERFACE_0, 9, 3, 0, | ||
704 | dac_boost_tlv), | ||
701 | SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, | 705 | SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, |
702 | wm8903_get_deemph, wm8903_put_deemph), | 706 | wm8903_get_deemph, wm8903_put_deemph), |
703 | 707 | ||
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index a64b93425ae3..0a4ffdd1d2a7 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -204,6 +204,7 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); | |||
204 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); | 204 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); |
205 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); | 205 | static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); |
206 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 206 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
207 | static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1); | ||
207 | 208 | ||
208 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { | 209 | static const struct snd_kcontrol_new wm8960_snd_controls[] = { |
209 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, | 210 | SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, |
@@ -213,6 +214,15 @@ SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, | |||
213 | SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, | 214 | SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, |
214 | 7, 1, 0), | 215 | 7, 1, 0), |
215 | 216 | ||
217 | SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume", | ||
218 | WM8960_INBMIX1, 4, 7, 0, boost_tlv), | ||
219 | SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume", | ||
220 | WM8960_INBMIX1, 1, 7, 0, boost_tlv), | ||
221 | SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume", | ||
222 | WM8960_INBMIX2, 4, 7, 0, boost_tlv), | ||
223 | SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume", | ||
224 | WM8960_INBMIX2, 1, 7, 0, boost_tlv), | ||
225 | |||
216 | SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, | 226 | SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, |
217 | 0, 255, 0, dac_tlv), | 227 | 0, 255, 0, dac_tlv), |
218 | 228 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c9bd445c4976..14094f558e03 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -2209,7 +2209,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2209 | vmid_reference(codec); | 2209 | vmid_reference(codec); |
2210 | break; | 2210 | break; |
2211 | case WM8958: | 2211 | case WM8958: |
2212 | if (wm8994->revision < 1) | 2212 | if (control->revision < 1) |
2213 | vmid_reference(codec); | 2213 | vmid_reference(codec); |
2214 | break; | 2214 | break; |
2215 | default: | 2215 | default: |
@@ -2244,7 +2244,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
2244 | vmid_dereference(codec); | 2244 | vmid_dereference(codec); |
2245 | break; | 2245 | break; |
2246 | case WM8958: | 2246 | case WM8958: |
2247 | if (wm8994->revision < 1) | 2247 | if (control->revision < 1) |
2248 | vmid_dereference(codec); | 2248 | vmid_dereference(codec); |
2249 | break; | 2249 | break; |
2250 | default: | 2250 | default: |
@@ -2268,10 +2268,26 @@ out: | |||
2268 | */ | 2268 | */ |
2269 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | 2269 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
2270 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | 2270 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); |
2271 | |||
2272 | wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) | ||
2273 | & WM8994_AIF1CLK_RATE_MASK; | ||
2274 | wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) | ||
2275 | & WM8994_AIF1CLK_RATE_MASK; | ||
2276 | |||
2271 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | 2277 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, |
2272 | WM8994_AIF1CLK_RATE_MASK, 0x1); | 2278 | WM8994_AIF1CLK_RATE_MASK, 0x1); |
2273 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | 2279 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, |
2274 | WM8994_AIF2CLK_RATE_MASK, 0x1); | 2280 | WM8994_AIF2CLK_RATE_MASK, 0x1); |
2281 | } else if (wm8994->aifdiv[0]) { | ||
2282 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2283 | WM8994_AIF1CLK_RATE_MASK, | ||
2284 | wm8994->aifdiv[0]); | ||
2285 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2286 | WM8994_AIF2CLK_RATE_MASK, | ||
2287 | wm8994->aifdiv[1]); | ||
2288 | |||
2289 | wm8994->aifdiv[0] = 0; | ||
2290 | wm8994->aifdiv[1] = 0; | ||
2275 | } | 2291 | } |
2276 | 2292 | ||
2277 | return 0; | 2293 | return 0; |
@@ -2368,10 +2384,26 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2368 | */ | 2384 | */ |
2369 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { | 2385 | if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { |
2370 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); | 2386 | dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); |
2387 | |||
2388 | wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) | ||
2389 | & WM8994_AIF1CLK_RATE_MASK; | ||
2390 | wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) | ||
2391 | & WM8994_AIF1CLK_RATE_MASK; | ||
2392 | |||
2371 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | 2393 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, |
2372 | WM8994_AIF1CLK_RATE_MASK, 0x1); | 2394 | WM8994_AIF1CLK_RATE_MASK, 0x1); |
2373 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | 2395 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, |
2374 | WM8994_AIF2CLK_RATE_MASK, 0x1); | 2396 | WM8994_AIF2CLK_RATE_MASK, 0x1); |
2397 | } else if (wm8994->aifdiv[0]) { | ||
2398 | snd_soc_update_bits(codec, WM8994_AIF1_RATE, | ||
2399 | WM8994_AIF1CLK_RATE_MASK, | ||
2400 | wm8994->aifdiv[0]); | ||
2401 | snd_soc_update_bits(codec, WM8994_AIF2_RATE, | ||
2402 | WM8994_AIF2CLK_RATE_MASK, | ||
2403 | wm8994->aifdiv[1]); | ||
2404 | |||
2405 | wm8994->aifdiv[0] = 0; | ||
2406 | wm8994->aifdiv[1] = 0; | ||
2375 | } | 2407 | } |
2376 | 2408 | ||
2377 | return 0; | 2409 | return 0; |
@@ -2411,7 +2443,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2411 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 2443 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
2412 | switch (control->type) { | 2444 | switch (control->type) { |
2413 | case WM8958: | 2445 | case WM8958: |
2414 | if (wm8994->revision == 0) { | 2446 | if (control->revision == 0) { |
2415 | /* Optimise performance for rev A */ | 2447 | /* Optimise performance for rev A */ |
2416 | snd_soc_update_bits(codec, | 2448 | snd_soc_update_bits(codec, |
2417 | WM8958_CHARGE_PUMP_2, | 2449 | WM8958_CHARGE_PUMP_2, |
@@ -2656,6 +2688,8 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2656 | { | 2688 | { |
2657 | struct snd_soc_codec *codec = dai->codec; | 2689 | struct snd_soc_codec *codec = dai->codec; |
2658 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2690 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2691 | struct wm8994 *control = wm8994->wm8994; | ||
2692 | struct wm8994_pdata *pdata = &control->pdata; | ||
2659 | int aif1_reg; | 2693 | int aif1_reg; |
2660 | int aif2_reg; | 2694 | int aif2_reg; |
2661 | int bclk_reg; | 2695 | int bclk_reg; |
@@ -2723,7 +2757,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2723 | } | 2757 | } |
2724 | 2758 | ||
2725 | wm8994->channels[id] = params_channels(params); | 2759 | wm8994->channels[id] = params_channels(params); |
2726 | switch (params_channels(params)) { | 2760 | if (pdata->max_channels_clocked[id] && |
2761 | wm8994->channels[id] > pdata->max_channels_clocked[id]) { | ||
2762 | dev_dbg(dai->dev, "Constraining channels to %d from %d\n", | ||
2763 | pdata->max_channels_clocked[id], wm8994->channels[id]); | ||
2764 | wm8994->channels[id] = pdata->max_channels_clocked[id]; | ||
2765 | } | ||
2766 | |||
2767 | switch (wm8994->channels[id]) { | ||
2727 | case 1: | 2768 | case 1: |
2728 | case 2: | 2769 | case 2: |
2729 | bclk_rate *= 2; | 2770 | bclk_rate *= 2; |
@@ -2745,7 +2786,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2745 | dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", | 2786 | dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", |
2746 | dai->id, wm8994->aifclk[id], bclk_rate); | 2787 | dai->id, wm8994->aifclk[id], bclk_rate); |
2747 | 2788 | ||
2748 | if (params_channels(params) == 1 && | 2789 | if (wm8994->channels[id] == 1 && |
2749 | (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) | 2790 | (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) |
2750 | aif2 |= WM8994_AIF1_MONO; | 2791 | aif2 |= WM8994_AIF1_MONO; |
2751 | 2792 | ||
@@ -3053,7 +3094,7 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec) | |||
3053 | int i, ret; | 3094 | int i, ret; |
3054 | unsigned int val, mask; | 3095 | unsigned int val, mask; |
3055 | 3096 | ||
3056 | if (wm8994->revision < 4) { | 3097 | if (control->revision < 4) { |
3057 | /* force a HW read */ | 3098 | /* force a HW read */ |
3058 | ret = regmap_read(control->regmap, | 3099 | ret = regmap_read(control->regmap, |
3059 | WM8994_POWER_MANAGEMENT_5, &val); | 3100 | WM8994_POWER_MANAGEMENT_5, &val); |
@@ -3870,7 +3911,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3870 | codec->dapm.idle_bias_off = 1; | 3911 | codec->dapm.idle_bias_off = 1; |
3871 | 3912 | ||
3872 | /* Set revision-specific configuration */ | 3913 | /* Set revision-specific configuration */ |
3873 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); | ||
3874 | switch (control->type) { | 3914 | switch (control->type) { |
3875 | case WM8994: | 3915 | case WM8994: |
3876 | /* Single ended line outputs should have VMID on. */ | 3916 | /* Single ended line outputs should have VMID on. */ |
@@ -3878,7 +3918,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3878 | !control->pdata.lineout2_diff) | 3918 | !control->pdata.lineout2_diff) |
3879 | codec->dapm.idle_bias_off = 0; | 3919 | codec->dapm.idle_bias_off = 0; |
3880 | 3920 | ||
3881 | switch (wm8994->revision) { | 3921 | switch (control->revision) { |
3882 | case 2: | 3922 | case 2: |
3883 | case 3: | 3923 | case 3: |
3884 | wm8994->hubs.dcs_codes_l = -5; | 3924 | wm8994->hubs.dcs_codes_l = -5; |
@@ -3897,7 +3937,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3897 | wm8994->hubs.dcs_readback_mode = 1; | 3937 | wm8994->hubs.dcs_readback_mode = 1; |
3898 | wm8994->hubs.hp_startup_mode = 1; | 3938 | wm8994->hubs.hp_startup_mode = 1; |
3899 | 3939 | ||
3900 | switch (wm8994->revision) { | 3940 | switch (control->revision) { |
3901 | case 0: | 3941 | case 0: |
3902 | break; | 3942 | break; |
3903 | default: | 3943 | default: |
@@ -4000,7 +4040,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4000 | 4040 | ||
4001 | switch (control->type) { | 4041 | switch (control->type) { |
4002 | case WM1811: | 4042 | case WM1811: |
4003 | if (control->cust_id > 1 || wm8994->revision > 1) { | 4043 | if (control->cust_id > 1 || control->revision > 1) { |
4004 | ret = wm8994_request_irq(wm8994->wm8994, | 4044 | ret = wm8994_request_irq(wm8994->wm8994, |
4005 | WM8994_IRQ_GPIO(6), | 4045 | WM8994_IRQ_GPIO(6), |
4006 | wm1811_jackdet_irq, "JACKDET", | 4046 | wm1811_jackdet_irq, "JACKDET", |
@@ -4114,7 +4154,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4114 | case WM8994: | 4154 | case WM8994: |
4115 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, | 4155 | snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, |
4116 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); | 4156 | ARRAY_SIZE(wm8994_specific_dapm_widgets)); |
4117 | if (wm8994->revision < 4) { | 4157 | if (control->revision < 4) { |
4118 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, | 4158 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, |
4119 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); | 4159 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); |
4120 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, | 4160 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, |
@@ -4135,7 +4175,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4135 | ARRAY_SIZE(wm8958_snd_controls)); | 4175 | ARRAY_SIZE(wm8958_snd_controls)); |
4136 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, | 4176 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, |
4137 | ARRAY_SIZE(wm8958_dapm_widgets)); | 4177 | ARRAY_SIZE(wm8958_dapm_widgets)); |
4138 | if (wm8994->revision < 1) { | 4178 | if (control->revision < 1) { |
4139 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, | 4179 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets, |
4140 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); | 4180 | ARRAY_SIZE(wm8994_lateclk_revd_widgets)); |
4141 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, | 4181 | snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets, |
@@ -4174,7 +4214,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4174 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 4214 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
4175 | ARRAY_SIZE(wm8994_intercon)); | 4215 | ARRAY_SIZE(wm8994_intercon)); |
4176 | 4216 | ||
4177 | if (wm8994->revision < 4) { | 4217 | if (control->revision < 4) { |
4178 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4218 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
4179 | ARRAY_SIZE(wm8994_revd_intercon)); | 4219 | ARRAY_SIZE(wm8994_revd_intercon)); |
4180 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, | 4220 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, |
@@ -4185,7 +4225,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4185 | } | 4225 | } |
4186 | break; | 4226 | break; |
4187 | case WM8958: | 4227 | case WM8958: |
4188 | if (wm8994->revision < 1) { | 4228 | if (control->revision < 1) { |
4189 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | 4229 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, |
4190 | ARRAY_SIZE(wm8994_intercon)); | 4230 | ARRAY_SIZE(wm8994_intercon)); |
4191 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4231 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 45f192702024..55ddf4d57d9b 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -79,6 +79,7 @@ struct wm8994_priv { | |||
79 | int sysclk_rate[2]; | 79 | int sysclk_rate[2]; |
80 | int mclk[2]; | 80 | int mclk[2]; |
81 | int aifclk[2]; | 81 | int aifclk[2]; |
82 | int aifdiv[2]; | ||
82 | int channels[2]; | 83 | int channels[2]; |
83 | struct wm8994_fll_config fll[2], fll_suspend[2]; | 84 | struct wm8994_fll_config fll[2], fll_suspend[2]; |
84 | struct completion fll_locked[2]; | 85 | struct completion fll_locked[2]; |
@@ -146,8 +147,6 @@ struct wm8994_priv { | |||
146 | wm1811_mic_id_cb mic_id_cb; | 147 | wm1811_mic_id_cb mic_id_cb; |
147 | void *mic_id_cb_data; | 148 | void *mic_id_cb_data; |
148 | 149 | ||
149 | int revision; | ||
150 | |||
151 | unsigned int aif1clk_enable:1; | 150 | unsigned int aif1clk_enable:1; |
152 | unsigned int aif2clk_enable:1; | 151 | unsigned int aif2clk_enable:1; |
153 | 152 | ||
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 9af1bddc4c62..3470b649c0b2 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <linux/mfd/arizona/registers.h> | 32 | #include <linux/mfd/arizona/registers.h> |
33 | 33 | ||
34 | #include "arizona.h" | ||
34 | #include "wm_adsp.h" | 35 | #include "wm_adsp.h" |
35 | 36 | ||
36 | #define adsp_crit(_dsp, fmt, ...) \ | 37 | #define adsp_crit(_dsp, fmt, ...) \ |
@@ -193,17 +194,25 @@ static void wm_adsp_buf_free(struct list_head *list) | |||
193 | 194 | ||
194 | #define WM_ADSP_NUM_FW 4 | 195 | #define WM_ADSP_NUM_FW 4 |
195 | 196 | ||
197 | #define WM_ADSP_FW_MBC_VSS 0 | ||
198 | #define WM_ADSP_FW_TX 1 | ||
199 | #define WM_ADSP_FW_TX_SPK 2 | ||
200 | #define WM_ADSP_FW_RX_ANC 3 | ||
201 | |||
196 | static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { | 202 | static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { |
197 | "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC" | 203 | [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", |
204 | [WM_ADSP_FW_TX] = "Tx", | ||
205 | [WM_ADSP_FW_TX_SPK] = "Tx Speaker", | ||
206 | [WM_ADSP_FW_RX_ANC] = "Rx ANC", | ||
198 | }; | 207 | }; |
199 | 208 | ||
200 | static struct { | 209 | static struct { |
201 | const char *file; | 210 | const char *file; |
202 | } wm_adsp_fw[WM_ADSP_NUM_FW] = { | 211 | } wm_adsp_fw[WM_ADSP_NUM_FW] = { |
203 | { .file = "mbc-vss" }, | 212 | [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, |
204 | { .file = "tx" }, | 213 | [WM_ADSP_FW_TX] = { .file = "tx" }, |
205 | { .file = "tx-spk" }, | 214 | [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, |
206 | { .file = "rx-anc" }, | 215 | [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, |
207 | }; | 216 | }; |
208 | 217 | ||
209 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, | 218 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, |
@@ -246,17 +255,52 @@ static const struct soc_enum wm_adsp_fw_enum[] = { | |||
246 | SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), | 255 | SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), |
247 | }; | 256 | }; |
248 | 257 | ||
249 | const struct snd_kcontrol_new wm_adsp_fw_controls[] = { | 258 | const struct snd_kcontrol_new wm_adsp1_fw_controls[] = { |
259 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], | ||
260 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
261 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], | ||
262 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
263 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], | ||
264 | wm_adsp_fw_get, wm_adsp_fw_put), | ||
265 | }; | ||
266 | EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); | ||
267 | |||
268 | #if IS_ENABLED(CONFIG_SND_SOC_ARIZONA) | ||
269 | static const struct soc_enum wm_adsp2_rate_enum[] = { | ||
270 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, | ||
271 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
272 | ARIZONA_RATE_ENUM_SIZE, | ||
273 | arizona_rate_text, arizona_rate_val), | ||
274 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1, | ||
275 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
276 | ARIZONA_RATE_ENUM_SIZE, | ||
277 | arizona_rate_text, arizona_rate_val), | ||
278 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, | ||
279 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
280 | ARIZONA_RATE_ENUM_SIZE, | ||
281 | arizona_rate_text, arizona_rate_val), | ||
282 | SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, | ||
283 | ARIZONA_DSP1_RATE_SHIFT, 0xf, | ||
284 | ARIZONA_RATE_ENUM_SIZE, | ||
285 | arizona_rate_text, arizona_rate_val), | ||
286 | }; | ||
287 | |||
288 | const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { | ||
250 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], | 289 | SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], |
251 | wm_adsp_fw_get, wm_adsp_fw_put), | 290 | wm_adsp_fw_get, wm_adsp_fw_put), |
291 | SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), | ||
252 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], | 292 | SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], |
253 | wm_adsp_fw_get, wm_adsp_fw_put), | 293 | wm_adsp_fw_get, wm_adsp_fw_put), |
294 | SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), | ||
254 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], | 295 | SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], |
255 | wm_adsp_fw_get, wm_adsp_fw_put), | 296 | wm_adsp_fw_get, wm_adsp_fw_put), |
297 | SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), | ||
256 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], | 298 | SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], |
257 | wm_adsp_fw_get, wm_adsp_fw_put), | 299 | wm_adsp_fw_get, wm_adsp_fw_put), |
300 | SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), | ||
258 | }; | 301 | }; |
259 | EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); | 302 | EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls); |
303 | #endif | ||
260 | 304 | ||
261 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, | 305 | static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, |
262 | int type) | 306 | int type) |
@@ -549,13 +593,30 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) | |||
549 | buf_size = sizeof(adsp1_id); | 593 | buf_size = sizeof(adsp1_id); |
550 | 594 | ||
551 | algs = be32_to_cpu(adsp1_id.algs); | 595 | algs = be32_to_cpu(adsp1_id.algs); |
596 | dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); | ||
552 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", | 597 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", |
553 | be32_to_cpu(adsp1_id.fw.id), | 598 | dsp->fw_id, |
554 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, | 599 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, |
555 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, | 600 | (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, |
556 | be32_to_cpu(adsp1_id.fw.ver) & 0xff, | 601 | be32_to_cpu(adsp1_id.fw.ver) & 0xff, |
557 | algs); | 602 | algs); |
558 | 603 | ||
604 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
605 | if (!region) | ||
606 | return -ENOMEM; | ||
607 | region->type = WMFW_ADSP1_ZM; | ||
608 | region->alg = be32_to_cpu(adsp1_id.fw.id); | ||
609 | region->base = be32_to_cpu(adsp1_id.zm); | ||
610 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
611 | |||
612 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
613 | if (!region) | ||
614 | return -ENOMEM; | ||
615 | region->type = WMFW_ADSP1_DM; | ||
616 | region->alg = be32_to_cpu(adsp1_id.fw.id); | ||
617 | region->base = be32_to_cpu(adsp1_id.dm); | ||
618 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
619 | |||
559 | pos = sizeof(adsp1_id) / 2; | 620 | pos = sizeof(adsp1_id) / 2; |
560 | term = pos + ((sizeof(*adsp1_alg) * algs) / 2); | 621 | term = pos + ((sizeof(*adsp1_alg) * algs) / 2); |
561 | break; | 622 | break; |
@@ -573,13 +634,38 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) | |||
573 | buf_size = sizeof(adsp2_id); | 634 | buf_size = sizeof(adsp2_id); |
574 | 635 | ||
575 | algs = be32_to_cpu(adsp2_id.algs); | 636 | algs = be32_to_cpu(adsp2_id.algs); |
637 | dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); | ||
576 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", | 638 | adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", |
577 | be32_to_cpu(adsp2_id.fw.id), | 639 | dsp->fw_id, |
578 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, | 640 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, |
579 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, | 641 | (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, |
580 | be32_to_cpu(adsp2_id.fw.ver) & 0xff, | 642 | be32_to_cpu(adsp2_id.fw.ver) & 0xff, |
581 | algs); | 643 | algs); |
582 | 644 | ||
645 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
646 | if (!region) | ||
647 | return -ENOMEM; | ||
648 | region->type = WMFW_ADSP2_XM; | ||
649 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
650 | region->base = be32_to_cpu(adsp2_id.xm); | ||
651 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
652 | |||
653 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
654 | if (!region) | ||
655 | return -ENOMEM; | ||
656 | region->type = WMFW_ADSP2_YM; | ||
657 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
658 | region->base = be32_to_cpu(adsp2_id.ym); | ||
659 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
660 | |||
661 | region = kzalloc(sizeof(*region), GFP_KERNEL); | ||
662 | if (!region) | ||
663 | return -ENOMEM; | ||
664 | region->type = WMFW_ADSP2_ZM; | ||
665 | region->alg = be32_to_cpu(adsp2_id.fw.id); | ||
666 | region->base = be32_to_cpu(adsp2_id.zm); | ||
667 | list_add_tail(®ion->list, &dsp->alg_regions); | ||
668 | |||
583 | pos = sizeof(adsp2_id) / 2; | 669 | pos = sizeof(adsp2_id) / 2; |
584 | term = pos + ((sizeof(*adsp2_alg) * algs) / 2); | 670 | term = pos + ((sizeof(*adsp2_alg) * algs) / 2); |
585 | break; | 671 | break; |
@@ -781,8 +867,24 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) | |||
781 | case (WMFW_INFO_TEXT << 8): | 867 | case (WMFW_INFO_TEXT << 8): |
782 | break; | 868 | break; |
783 | case (WMFW_ABSOLUTE << 8): | 869 | case (WMFW_ABSOLUTE << 8): |
784 | region_name = "register"; | 870 | /* |
785 | reg = offset; | 871 | * Old files may use this for global |
872 | * coefficients. | ||
873 | */ | ||
874 | if (le32_to_cpu(blk->id) == dsp->fw_id && | ||
875 | offset == 0) { | ||
876 | region_name = "global coefficients"; | ||
877 | mem = wm_adsp_find_region(dsp, type); | ||
878 | if (!mem) { | ||
879 | adsp_err(dsp, "No ZM\n"); | ||
880 | break; | ||
881 | } | ||
882 | reg = wm_adsp_region_to_reg(mem, 0); | ||
883 | |||
884 | } else { | ||
885 | region_name = "register"; | ||
886 | reg = offset; | ||
887 | } | ||
786 | break; | 888 | break; |
787 | 889 | ||
788 | case WMFW_ADSP1_DM: | 890 | case WMFW_ADSP1_DM: |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index cb8871a3ec00..fea514627526 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
@@ -46,6 +46,8 @@ struct wm_adsp { | |||
46 | 46 | ||
47 | struct list_head alg_regions; | 47 | struct list_head alg_regions; |
48 | 48 | ||
49 | int fw_id; | ||
50 | |||
49 | const struct wm_adsp_region *mem; | 51 | const struct wm_adsp_region *mem; |
50 | int num_mems; | 52 | int num_mems; |
51 | 53 | ||
@@ -65,7 +67,8 @@ struct wm_adsp { | |||
65 | .shift = num, .event = wm_adsp2_event, \ | 67 | .shift = num, .event = wm_adsp2_event, \ |
66 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | 68 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } |
67 | 69 | ||
68 | extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; | 70 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; |
71 | extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; | ||
69 | 72 | ||
70 | int wm_adsp1_init(struct wm_adsp *adsp); | 73 | int wm_adsp1_init(struct wm_adsp *adsp); |
71 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); | 74 | int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 867ae97ddcec..f5d81b948759 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -199,11 +199,12 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg) | |||
199 | list_add_tail(&cache->list, &hubs->dcs_cache); | 199 | list_add_tail(&cache->list, &hubs->dcs_cache); |
200 | } | 200 | } |
201 | 201 | ||
202 | static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, | 202 | static int wm_hubs_read_dc_servo(struct snd_soc_codec *codec, |
203 | u16 *reg_l, u16 *reg_r) | 203 | u16 *reg_l, u16 *reg_r) |
204 | { | 204 | { |
205 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 205 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
206 | u16 dcs_reg, reg; | 206 | u16 dcs_reg, reg; |
207 | int ret = 0; | ||
207 | 208 | ||
208 | switch (hubs->dcs_readback_mode) { | 209 | switch (hubs->dcs_readback_mode) { |
209 | case 2: | 210 | case 2: |
@@ -236,8 +237,9 @@ static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, | |||
236 | break; | 237 | break; |
237 | default: | 238 | default: |
238 | WARN(1, "Unknown DCS readback method\n"); | 239 | WARN(1, "Unknown DCS readback method\n"); |
239 | return; | 240 | ret = -1; |
240 | } | 241 | } |
242 | return ret; | ||
241 | } | 243 | } |
242 | 244 | ||
243 | /* | 245 | /* |
@@ -286,7 +288,8 @@ static void enable_dc_servo(struct snd_soc_codec *codec) | |||
286 | WM8993_DCS_TRIG_STARTUP_1); | 288 | WM8993_DCS_TRIG_STARTUP_1); |
287 | } | 289 | } |
288 | 290 | ||
289 | wm_hubs_read_dc_servo(codec, ®_l, ®_r); | 291 | if (wm_hubs_read_dc_servo(codec, ®_l, ®_r) < 0) |
292 | return; | ||
290 | 293 | ||
291 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); | 294 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); |
292 | 295 | ||
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 821831207180..ebe82947bab3 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -645,6 +645,10 @@ static struct snd_soc_dai_driver davinci_i2s_dai = { | |||
645 | 645 | ||
646 | }; | 646 | }; |
647 | 647 | ||
648 | static const struct snd_soc_component_driver davinci_i2s_component = { | ||
649 | .name = "davinci-i2s", | ||
650 | }; | ||
651 | |||
648 | static int davinci_i2s_probe(struct platform_device *pdev) | 652 | static int davinci_i2s_probe(struct platform_device *pdev) |
649 | { | 653 | { |
650 | struct snd_platform_data *pdata = pdev->dev.platform_data; | 654 | struct snd_platform_data *pdata = pdev->dev.platform_data; |
@@ -727,20 +731,21 @@ static int davinci_i2s_probe(struct platform_device *pdev) | |||
727 | 731 | ||
728 | dev_set_drvdata(&pdev->dev, dev); | 732 | dev_set_drvdata(&pdev->dev, dev); |
729 | 733 | ||
730 | ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); | 734 | ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component, |
735 | &davinci_i2s_dai, 1); | ||
731 | if (ret != 0) | 736 | if (ret != 0) |
732 | goto err_release_clk; | 737 | goto err_release_clk; |
733 | 738 | ||
734 | ret = davinci_soc_platform_register(&pdev->dev); | 739 | ret = davinci_soc_platform_register(&pdev->dev); |
735 | if (ret) { | 740 | if (ret) { |
736 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | 741 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); |
737 | goto err_unregister_dai; | 742 | goto err_unregister_component; |
738 | } | 743 | } |
739 | 744 | ||
740 | return 0; | 745 | return 0; |
741 | 746 | ||
742 | err_unregister_dai: | 747 | err_unregister_component: |
743 | snd_soc_unregister_dai(&pdev->dev); | 748 | snd_soc_unregister_component(&pdev->dev); |
744 | err_release_clk: | 749 | err_release_clk: |
745 | clk_disable(dev->clk); | 750 | clk_disable(dev->clk); |
746 | clk_put(dev->clk); | 751 | clk_put(dev->clk); |
@@ -751,7 +756,7 @@ static int davinci_i2s_remove(struct platform_device *pdev) | |||
751 | { | 756 | { |
752 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); | 757 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); |
753 | 758 | ||
754 | snd_soc_unregister_dai(&pdev->dev); | 759 | snd_soc_unregister_component(&pdev->dev); |
755 | davinci_soc_platform_unregister(&pdev->dev); | 760 | davinci_soc_platform_unregister(&pdev->dev); |
756 | 761 | ||
757 | clk_disable(dev->clk); | 762 | clk_disable(dev->clk); |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9321e5c9d8c1..8b85049daab0 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -235,6 +235,8 @@ | |||
235 | #define DISMOD (val)(val<<2) | 235 | #define DISMOD (val)(val<<2) |
236 | #define TXSTATE BIT(4) | 236 | #define TXSTATE BIT(4) |
237 | #define RXSTATE BIT(5) | 237 | #define RXSTATE BIT(5) |
238 | #define SRMOD_MASK 3 | ||
239 | #define SRMOD_INACTIVE 0 | ||
238 | 240 | ||
239 | /* | 241 | /* |
240 | * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits | 242 | * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits |
@@ -634,35 +636,43 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, | |||
634 | * callback, take it into account here. That allows us to for example | 636 | * callback, take it into account here. That allows us to for example |
635 | * send 32 bits per channel to the codec, while only 16 of them carry | 637 | * send 32 bits per channel to the codec, while only 16 of them carry |
636 | * audio payload. | 638 | * audio payload. |
637 | * The clock ratio is given for a full period of data (both left and | 639 | * The clock ratio is given for a full period of data (for I2S format |
638 | * right channels), so it has to be divided by 2. | 640 | * both left and right channels), so it has to be divided by number of |
641 | * tdm-slots (for I2S - divided by 2). | ||
639 | */ | 642 | */ |
640 | if (dev->bclk_lrclk_ratio) | 643 | if (dev->bclk_lrclk_ratio) |
641 | word_length = dev->bclk_lrclk_ratio / 2; | 644 | word_length = dev->bclk_lrclk_ratio / dev->tdm_slots; |
642 | 645 | ||
643 | /* mapping of the XSSZ bit-field as described in the datasheet */ | 646 | /* mapping of the XSSZ bit-field as described in the datasheet */ |
644 | fmt = (word_length >> 1) - 1; | 647 | fmt = (word_length >> 1) - 1; |
645 | 648 | ||
646 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, | 649 | if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) { |
647 | RXSSZ(fmt), RXSSZ(0x0F)); | 650 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, |
648 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, | 651 | RXSSZ(fmt), RXSSZ(0x0F)); |
649 | TXSSZ(fmt), TXSSZ(0x0F)); | 652 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
650 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXROT(rotate), | 653 | TXSSZ(fmt), TXSSZ(0x0F)); |
651 | TXROT(7)); | 654 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
652 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXROT(rotate), | 655 | TXROT(rotate), TXROT(7)); |
653 | RXROT(7)); | 656 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, |
657 | RXROT(rotate), RXROT(7)); | ||
658 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, | ||
659 | mask); | ||
660 | } | ||
661 | |||
654 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); | 662 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); |
655 | mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, mask); | ||
656 | 663 | ||
657 | return 0; | 664 | return 0; |
658 | } | 665 | } |
659 | 666 | ||
660 | static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | 667 | static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, |
668 | int channels) | ||
661 | { | 669 | { |
662 | int i; | 670 | int i; |
663 | u8 tx_ser = 0; | 671 | u8 tx_ser = 0; |
664 | u8 rx_ser = 0; | 672 | u8 rx_ser = 0; |
665 | 673 | u8 ser; | |
674 | u8 slots = dev->tdm_slots; | ||
675 | u8 max_active_serializers = (channels + slots - 1) / slots; | ||
666 | /* Default configuration */ | 676 | /* Default configuration */ |
667 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); | 677 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); |
668 | 678 | ||
@@ -682,17 +692,33 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | |||
682 | for (i = 0; i < dev->num_serializer; i++) { | 692 | for (i = 0; i < dev->num_serializer; i++) { |
683 | mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), | 693 | mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), |
684 | dev->serial_dir[i]); | 694 | dev->serial_dir[i]); |
685 | if (dev->serial_dir[i] == TX_MODE) { | 695 | if (dev->serial_dir[i] == TX_MODE && |
696 | tx_ser < max_active_serializers) { | ||
686 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, | 697 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, |
687 | AXR(i)); | 698 | AXR(i)); |
688 | tx_ser++; | 699 | tx_ser++; |
689 | } else if (dev->serial_dir[i] == RX_MODE) { | 700 | } else if (dev->serial_dir[i] == RX_MODE && |
701 | rx_ser < max_active_serializers) { | ||
690 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, | 702 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, |
691 | AXR(i)); | 703 | AXR(i)); |
692 | rx_ser++; | 704 | rx_ser++; |
705 | } else { | ||
706 | mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), | ||
707 | SRMOD_INACTIVE, SRMOD_MASK); | ||
693 | } | 708 | } |
694 | } | 709 | } |
695 | 710 | ||
711 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
712 | ser = tx_ser; | ||
713 | else | ||
714 | ser = rx_ser; | ||
715 | |||
716 | if (ser < max_active_serializers) { | ||
717 | dev_warn(dev->dev, "stream has more channels (%d) than are " | ||
718 | "enabled in mcasp (%d)\n", channels, ser * slots); | ||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
696 | if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { | 722 | if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { |
697 | if (dev->txnumevt * tx_ser > 64) | 723 | if (dev->txnumevt * tx_ser > 64) |
698 | dev->txnumevt = 1; | 724 | dev->txnumevt = 1; |
@@ -729,6 +755,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) | |||
729 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); | 755 | ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); |
730 | } | 756 | } |
731 | } | 757 | } |
758 | |||
759 | return 0; | ||
732 | } | 760 | } |
733 | 761 | ||
734 | static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | 762 | static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) |
@@ -772,12 +800,6 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) | |||
772 | /* S/PDIF */ | 800 | /* S/PDIF */ |
773 | static void davinci_hw_dit_param(struct davinci_audio_dev *dev) | 801 | static void davinci_hw_dit_param(struct davinci_audio_dev *dev) |
774 | { | 802 | { |
775 | /* Set the PDIR for Serialiser as output */ | ||
776 | mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX); | ||
777 | |||
778 | /* TXMASK for 24 bits */ | ||
779 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF); | ||
780 | |||
781 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 | 803 | /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 |
782 | and LSB first */ | 804 | and LSB first */ |
783 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, | 805 | mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, |
@@ -812,12 +834,21 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
812 | &dev->dma_params[substream->stream]; | 834 | &dev->dma_params[substream->stream]; |
813 | int word_length; | 835 | int word_length; |
814 | u8 fifo_level; | 836 | u8 fifo_level; |
837 | u8 slots = dev->tdm_slots; | ||
838 | u8 active_serializers; | ||
839 | int channels; | ||
840 | struct snd_interval *pcm_channels = hw_param_interval(params, | ||
841 | SNDRV_PCM_HW_PARAM_CHANNELS); | ||
842 | channels = pcm_channels->min; | ||
843 | |||
844 | active_serializers = (channels + slots - 1) / slots; | ||
815 | 845 | ||
816 | davinci_hw_common_param(dev, substream->stream); | 846 | if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL) |
847 | return -EINVAL; | ||
817 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 848 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
818 | fifo_level = dev->txnumevt; | 849 | fifo_level = dev->txnumevt * active_serializers; |
819 | else | 850 | else |
820 | fifo_level = dev->rxnumevt; | 851 | fifo_level = dev->rxnumevt * active_serializers; |
821 | 852 | ||
822 | if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) | 853 | if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) |
823 | davinci_hw_dit_param(dev); | 854 | davinci_hw_dit_param(dev); |
@@ -936,13 +967,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
936 | .name = "davinci-mcasp.0", | 967 | .name = "davinci-mcasp.0", |
937 | .playback = { | 968 | .playback = { |
938 | .channels_min = 2, | 969 | .channels_min = 2, |
939 | .channels_max = 2, | 970 | .channels_max = 32 * 16, |
940 | .rates = DAVINCI_MCASP_RATES, | 971 | .rates = DAVINCI_MCASP_RATES, |
941 | .formats = DAVINCI_MCASP_PCM_FMTS, | 972 | .formats = DAVINCI_MCASP_PCM_FMTS, |
942 | }, | 973 | }, |
943 | .capture = { | 974 | .capture = { |
944 | .channels_min = 2, | 975 | .channels_min = 2, |
945 | .channels_max = 2, | 976 | .channels_max = 32 * 16, |
946 | .rates = DAVINCI_MCASP_RATES, | 977 | .rates = DAVINCI_MCASP_RATES, |
947 | .formats = DAVINCI_MCASP_PCM_FMTS, | 978 | .formats = DAVINCI_MCASP_PCM_FMTS, |
948 | }, | 979 | }, |
@@ -962,6 +993,10 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
962 | 993 | ||
963 | }; | 994 | }; |
964 | 995 | ||
996 | static const struct snd_soc_component_driver davinci_mcasp_component = { | ||
997 | .name = "davinci-mcasp", | ||
998 | }; | ||
999 | |||
965 | static const struct of_device_id mcasp_dt_ids[] = { | 1000 | static const struct of_device_id mcasp_dt_ids[] = { |
966 | { | 1001 | { |
967 | .compatible = "ti,dm646x-mcasp-audio", | 1002 | .compatible = "ti,dm646x-mcasp-audio", |
@@ -1015,8 +1050,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( | |||
1015 | pdata->op_mode = val; | 1050 | pdata->op_mode = val; |
1016 | 1051 | ||
1017 | ret = of_property_read_u32(np, "tdm-slots", &val); | 1052 | ret = of_property_read_u32(np, "tdm-slots", &val); |
1018 | if (ret >= 0) | 1053 | if (ret >= 0) { |
1054 | if (val < 2 || val > 32) { | ||
1055 | dev_err(&pdev->dev, | ||
1056 | "tdm-slots must be in rage [2-32]\n"); | ||
1057 | ret = -EINVAL; | ||
1058 | goto nodata; | ||
1059 | } | ||
1060 | |||
1019 | pdata->tdm_slots = val; | 1061 | pdata->tdm_slots = val; |
1062 | } | ||
1020 | 1063 | ||
1021 | ret = of_property_read_u32(np, "num-serializer", &val); | 1064 | ret = of_property_read_u32(np, "num-serializer", &val); |
1022 | if (ret >= 0) | 1065 | if (ret >= 0) |
@@ -1170,7 +1213,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1170 | 1213 | ||
1171 | dma_data->channel = res->start; | 1214 | dma_data->channel = res->start; |
1172 | dev_set_drvdata(&pdev->dev, dev); | 1215 | dev_set_drvdata(&pdev->dev, dev); |
1173 | ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); | 1216 | ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, |
1217 | &davinci_mcasp_dai[pdata->op_mode], 1); | ||
1174 | 1218 | ||
1175 | if (ret != 0) | 1219 | if (ret != 0) |
1176 | goto err_release_clk; | 1220 | goto err_release_clk; |
@@ -1178,13 +1222,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1178 | ret = davinci_soc_platform_register(&pdev->dev); | 1222 | ret = davinci_soc_platform_register(&pdev->dev); |
1179 | if (ret) { | 1223 | if (ret) { |
1180 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | 1224 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); |
1181 | goto err_unregister_dai; | 1225 | goto err_unregister_component; |
1182 | } | 1226 | } |
1183 | 1227 | ||
1184 | return 0; | 1228 | return 0; |
1185 | 1229 | ||
1186 | err_unregister_dai: | 1230 | err_unregister_component: |
1187 | snd_soc_unregister_dai(&pdev->dev); | 1231 | snd_soc_unregister_component(&pdev->dev); |
1188 | err_release_clk: | 1232 | err_release_clk: |
1189 | pm_runtime_put_sync(&pdev->dev); | 1233 | pm_runtime_put_sync(&pdev->dev); |
1190 | pm_runtime_disable(&pdev->dev); | 1234 | pm_runtime_disable(&pdev->dev); |
@@ -1194,7 +1238,7 @@ err_release_clk: | |||
1194 | static int davinci_mcasp_remove(struct platform_device *pdev) | 1238 | static int davinci_mcasp_remove(struct platform_device *pdev) |
1195 | { | 1239 | { |
1196 | 1240 | ||
1197 | snd_soc_unregister_dai(&pdev->dev); | 1241 | snd_soc_unregister_component(&pdev->dev); |
1198 | davinci_soc_platform_unregister(&pdev->dev); | 1242 | davinci_soc_platform_unregister(&pdev->dev); |
1199 | 1243 | ||
1200 | pm_runtime_put_sync(&pdev->dev); | 1244 | pm_runtime_put_sync(&pdev->dev); |
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 0edd3b5a37fd..a9ac0c11da71 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -38,7 +38,7 @@ struct davinci_audio_dev { | |||
38 | u8 num_serializer; | 38 | u8 num_serializer; |
39 | u8 *serial_dir; | 39 | u8 *serial_dir; |
40 | u8 version; | 40 | u8 version; |
41 | u8 bclk_lrclk_ratio; | 41 | u16 bclk_lrclk_ratio; |
42 | 42 | ||
43 | /* McASP FIFO related */ | 43 | /* McASP FIFO related */ |
44 | u8 txnumevt; | 44 | u8 txnumevt; |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index afab81f844ae..b2f27c2e5fdc 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -200,7 +200,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
200 | src = dma_pos; | 200 | src = dma_pos; |
201 | dst = prtd->params->dma_addr; | 201 | dst = prtd->params->dma_addr; |
202 | src_bidx = data_type; | 202 | src_bidx = data_type; |
203 | dst_bidx = 0; | 203 | dst_bidx = 4; |
204 | src_cidx = data_type * fifo_level; | 204 | src_cidx = data_type * fifo_level; |
205 | dst_cidx = 0; | 205 | dst_cidx = 0; |
206 | } else { | 206 | } else { |
@@ -223,9 +223,10 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
223 | edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, | 223 | edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, |
224 | ASYNC); | 224 | ASYNC); |
225 | else | 225 | else |
226 | edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, | 226 | edma_set_transfer_params(prtd->asp_link[0], acnt, |
227 | count, fifo_level, | 227 | fifo_level, |
228 | ABSYNC); | 228 | count, fifo_level, |
229 | ABSYNC); | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) | 232 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) |
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 07bde2e6f84e..30587c0cdbd2 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c | |||
@@ -204,6 +204,10 @@ static struct snd_soc_dai_driver davinci_vcif_dai = { | |||
204 | 204 | ||
205 | }; | 205 | }; |
206 | 206 | ||
207 | static const struct snd_soc_component_driver davinci_vcif_component = { | ||
208 | .name = "davinci-vcif", | ||
209 | }; | ||
210 | |||
207 | static int davinci_vcif_probe(struct platform_device *pdev) | 211 | static int davinci_vcif_probe(struct platform_device *pdev) |
208 | { | 212 | { |
209 | struct davinci_vc *davinci_vc = pdev->dev.platform_data; | 213 | struct davinci_vc *davinci_vc = pdev->dev.platform_data; |
@@ -234,7 +238,8 @@ static int davinci_vcif_probe(struct platform_device *pdev) | |||
234 | 238 | ||
235 | dev_set_drvdata(&pdev->dev, davinci_vcif_dev); | 239 | dev_set_drvdata(&pdev->dev, davinci_vcif_dev); |
236 | 240 | ||
237 | ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai); | 241 | ret = snd_soc_register_component(&pdev->dev, &davinci_vcif_component, |
242 | &davinci_vcif_dai, 1); | ||
238 | if (ret != 0) { | 243 | if (ret != 0) { |
239 | dev_err(&pdev->dev, "could not register dai\n"); | 244 | dev_err(&pdev->dev, "could not register dai\n"); |
240 | return ret; | 245 | return ret; |
@@ -243,7 +248,7 @@ static int davinci_vcif_probe(struct platform_device *pdev) | |||
243 | ret = davinci_soc_platform_register(&pdev->dev); | 248 | ret = davinci_soc_platform_register(&pdev->dev); |
244 | if (ret) { | 249 | if (ret) { |
245 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | 250 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); |
246 | snd_soc_unregister_dai(&pdev->dev); | 251 | snd_soc_unregister_component(&pdev->dev); |
247 | return ret; | 252 | return ret; |
248 | } | 253 | } |
249 | 254 | ||
@@ -252,7 +257,7 @@ static int davinci_vcif_probe(struct platform_device *pdev) | |||
252 | 257 | ||
253 | static int davinci_vcif_remove(struct platform_device *pdev) | 258 | static int davinci_vcif_remove(struct platform_device *pdev) |
254 | { | 259 | { |
255 | snd_soc_unregister_dai(&pdev->dev); | 260 | snd_soc_unregister_component(&pdev->dev); |
256 | davinci_soc_platform_unregister(&pdev->dev); | 261 | davinci_soc_platform_unregister(&pdev->dev); |
257 | 262 | ||
258 | return 0; | 263 | return 0; |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index deb30d59965e..593a3ea12d4c 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -297,6 +297,10 @@ static struct snd_soc_dai_ops dw_i2s_dai_ops = { | |||
297 | .trigger = dw_i2s_trigger, | 297 | .trigger = dw_i2s_trigger, |
298 | }; | 298 | }; |
299 | 299 | ||
300 | static const struct snd_soc_component_driver dw_i2s_component = { | ||
301 | .name = "dw-i2s", | ||
302 | }; | ||
303 | |||
300 | #ifdef CONFIG_PM | 304 | #ifdef CONFIG_PM |
301 | 305 | ||
302 | static int dw_i2s_suspend(struct snd_soc_dai *dai) | 306 | static int dw_i2s_suspend(struct snd_soc_dai *dai) |
@@ -413,7 +417,8 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
413 | 417 | ||
414 | dev->dev = &pdev->dev; | 418 | dev->dev = &pdev->dev; |
415 | dev_set_drvdata(&pdev->dev, dev); | 419 | dev_set_drvdata(&pdev->dev, dev); |
416 | ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai); | 420 | ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, |
421 | dw_i2s_dai, 1); | ||
417 | if (ret != 0) { | 422 | if (ret != 0) { |
418 | dev_err(&pdev->dev, "not able to register dai\n"); | 423 | dev_err(&pdev->dev, "not able to register dai\n"); |
419 | goto err_set_drvdata; | 424 | goto err_set_drvdata; |
@@ -434,7 +439,7 @@ static int dw_i2s_remove(struct platform_device *pdev) | |||
434 | { | 439 | { |
435 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); | 440 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); |
436 | 441 | ||
437 | snd_soc_unregister_dai(&pdev->dev); | 442 | snd_soc_unregister_component(&pdev->dev); |
438 | dev_set_drvdata(&pdev->dev, NULL); | 443 | dev_set_drvdata(&pdev->dev, NULL); |
439 | 444 | ||
440 | clk_put(dev->clk); | 445 | clk_put(dev->clk); |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 3b98159d9645..3843a18d4e56 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -118,7 +118,7 @@ config SND_SOC_IMX_PCM_FIQ | |||
118 | 118 | ||
119 | config SND_SOC_IMX_PCM_DMA | 119 | config SND_SOC_IMX_PCM_DMA |
120 | bool | 120 | bool |
121 | select SND_SOC_DMAENGINE_PCM | 121 | select SND_SOC_GENERIC_DMAENGINE_PCM |
122 | select SND_SOC_IMX_PCM | 122 | select SND_SOC_IMX_PCM |
123 | 123 | ||
124 | config SND_SOC_IMX_AUDMUX | 124 | config SND_SOC_IMX_AUDMUX |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7decbd9b2340..0f0bed6def9e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
28 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
29 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
30 | #include <sound/dmaengine_pcm.h> | ||
30 | 31 | ||
31 | #include "fsl_ssi.h" | 32 | #include "fsl_ssi.h" |
32 | #include "imx-pcm.h" | 33 | #include "imx-pcm.h" |
@@ -122,8 +123,10 @@ struct fsl_ssi_private { | |||
122 | bool ssi_on_imx; | 123 | bool ssi_on_imx; |
123 | struct clk *clk; | 124 | struct clk *clk; |
124 | struct platform_device *imx_pcm_pdev; | 125 | struct platform_device *imx_pcm_pdev; |
125 | struct imx_pcm_dma_params dma_params_tx; | 126 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
126 | struct imx_pcm_dma_params dma_params_rx; | 127 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
128 | struct imx_dma_data filter_data_tx; | ||
129 | struct imx_dma_data filter_data_rx; | ||
127 | 130 | ||
128 | struct { | 131 | struct { |
129 | unsigned int rfrc; | 132 | unsigned int rfrc; |
@@ -422,12 +425,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
422 | ssi_private->second_stream = substream; | 425 | ssi_private->second_stream = substream; |
423 | } | 426 | } |
424 | 427 | ||
425 | if (ssi_private->ssi_on_imx) | ||
426 | snd_soc_dai_set_dma_data(dai, substream, | ||
427 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
428 | &ssi_private->dma_params_tx : | ||
429 | &ssi_private->dma_params_rx); | ||
430 | |||
431 | return 0; | 428 | return 0; |
432 | } | 429 | } |
433 | 430 | ||
@@ -549,6 +546,18 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, | |||
549 | } | 546 | } |
550 | } | 547 | } |
551 | 548 | ||
549 | static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) | ||
550 | { | ||
551 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); | ||
552 | |||
553 | if (ssi_private->ssi_on_imx) { | ||
554 | dai->playback_dma_data = &ssi_private->dma_params_tx; | ||
555 | dai->capture_dma_data = &ssi_private->dma_params_rx; | ||
556 | } | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
552 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { | 561 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { |
553 | .startup = fsl_ssi_startup, | 562 | .startup = fsl_ssi_startup, |
554 | .hw_params = fsl_ssi_hw_params, | 563 | .hw_params = fsl_ssi_hw_params, |
@@ -558,6 +567,7 @@ static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { | |||
558 | 567 | ||
559 | /* Template for the CPU dai driver structure */ | 568 | /* Template for the CPU dai driver structure */ |
560 | static struct snd_soc_dai_driver fsl_ssi_dai_template = { | 569 | static struct snd_soc_dai_driver fsl_ssi_dai_template = { |
570 | .probe = fsl_ssi_dai_probe, | ||
561 | .playback = { | 571 | .playback = { |
562 | /* The SSI does not support monaural audio. */ | 572 | /* The SSI does not support monaural audio. */ |
563 | .channels_min = 2, | 573 | .channels_min = 2, |
@@ -574,6 +584,10 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = { | |||
574 | .ops = &fsl_ssi_dai_ops, | 584 | .ops = &fsl_ssi_dai_ops, |
575 | }; | 585 | }; |
576 | 586 | ||
587 | static const struct snd_soc_component_driver fsl_ssi_component = { | ||
588 | .name = "fsl-ssi", | ||
589 | }; | ||
590 | |||
577 | /* Show the statistics of a flag only if its interrupt is enabled. The | 591 | /* Show the statistics of a flag only if its interrupt is enabled. The |
578 | * compiler will optimze this code to a no-op if the interrupt is not | 592 | * compiler will optimze this code to a no-op if the interrupt is not |
579 | * enabled. | 593 | * enabled. |
@@ -649,6 +663,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
649 | const uint32_t *iprop; | 663 | const uint32_t *iprop; |
650 | struct resource res; | 664 | struct resource res; |
651 | char name[64]; | 665 | char name[64]; |
666 | bool shared; | ||
652 | 667 | ||
653 | /* SSIs that are not connected on the board should have a | 668 | /* SSIs that are not connected on the board should have a |
654 | * status = "disabled" | 669 | * status = "disabled" |
@@ -737,14 +752,18 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
737 | * We have burstsize be "fifo_depth - 2" to match the SSI | 752 | * We have burstsize be "fifo_depth - 2" to match the SSI |
738 | * watermark setting in fsl_ssi_startup(). | 753 | * watermark setting in fsl_ssi_startup(). |
739 | */ | 754 | */ |
740 | ssi_private->dma_params_tx.burstsize = | 755 | ssi_private->dma_params_tx.maxburst = |
741 | ssi_private->fifo_depth - 2; | 756 | ssi_private->fifo_depth - 2; |
742 | ssi_private->dma_params_rx.burstsize = | 757 | ssi_private->dma_params_rx.maxburst = |
743 | ssi_private->fifo_depth - 2; | 758 | ssi_private->fifo_depth - 2; |
744 | ssi_private->dma_params_tx.dma_addr = | 759 | ssi_private->dma_params_tx.addr = |
745 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); | 760 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); |
746 | ssi_private->dma_params_rx.dma_addr = | 761 | ssi_private->dma_params_rx.addr = |
747 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); | 762 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); |
763 | ssi_private->dma_params_tx.filter_data = | ||
764 | &ssi_private->filter_data_tx; | ||
765 | ssi_private->dma_params_rx.filter_data = | ||
766 | &ssi_private->filter_data_rx; | ||
748 | /* | 767 | /* |
749 | * TODO: This is a temporary solution and should be changed | 768 | * TODO: This is a temporary solution and should be changed |
750 | * to use generic DMA binding later when the helplers get in. | 769 | * to use generic DMA binding later when the helplers get in. |
@@ -755,14 +774,14 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
755 | dev_err(&pdev->dev, "could not get dma events\n"); | 774 | dev_err(&pdev->dev, "could not get dma events\n"); |
756 | goto error_clk; | 775 | goto error_clk; |
757 | } | 776 | } |
758 | ssi_private->dma_params_tx.dma = dma_events[0]; | ||
759 | ssi_private->dma_params_rx.dma = dma_events[1]; | ||
760 | 777 | ||
761 | ssi_private->dma_params_tx.shared_peripheral = | 778 | shared = of_device_is_compatible(of_get_parent(np), |
762 | of_device_is_compatible(of_get_parent(np), | 779 | "fsl,spba-bus"); |
763 | "fsl,spba-bus"); | 780 | |
764 | ssi_private->dma_params_rx.shared_peripheral = | 781 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx, |
765 | ssi_private->dma_params_tx.shared_peripheral; | 782 | dma_events[0], shared); |
783 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, | ||
784 | dma_events[1], shared); | ||
766 | } | 785 | } |
767 | 786 | ||
768 | /* Initialize the the device_attribute structure */ | 787 | /* Initialize the the device_attribute structure */ |
@@ -782,7 +801,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
782 | /* Register with ASoC */ | 801 | /* Register with ASoC */ |
783 | dev_set_drvdata(&pdev->dev, ssi_private); | 802 | dev_set_drvdata(&pdev->dev, ssi_private); |
784 | 803 | ||
785 | ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); | 804 | ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, |
805 | &ssi_private->cpu_dai_drv, 1); | ||
786 | if (ret) { | 806 | if (ret) { |
787 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | 807 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); |
788 | goto error_dev; | 808 | goto error_dev; |
@@ -835,7 +855,7 @@ done: | |||
835 | error_dai: | 855 | error_dai: |
836 | if (ssi_private->ssi_on_imx) | 856 | if (ssi_private->ssi_on_imx) |
837 | platform_device_unregister(ssi_private->imx_pcm_pdev); | 857 | platform_device_unregister(ssi_private->imx_pcm_pdev); |
838 | snd_soc_unregister_dai(&pdev->dev); | 858 | snd_soc_unregister_component(&pdev->dev); |
839 | 859 | ||
840 | error_dev: | 860 | error_dev: |
841 | dev_set_drvdata(&pdev->dev, NULL); | 861 | dev_set_drvdata(&pdev->dev, NULL); |
@@ -873,7 +893,7 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
873 | clk_disable_unprepare(ssi_private->clk); | 893 | clk_disable_unprepare(ssi_private->clk); |
874 | clk_put(ssi_private->clk); | 894 | clk_put(ssi_private->clk); |
875 | } | 895 | } |
876 | snd_soc_unregister_dai(&pdev->dev); | 896 | snd_soc_unregister_component(&pdev->dev); |
877 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); | 897 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); |
878 | 898 | ||
879 | free_irq(ssi_private->irq, ssi_private); | 899 | free_irq(ssi_private->irq, ssi_private); |
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index 217300029b5b..e6b9a69e2a68 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h | |||
@@ -196,5 +196,13 @@ struct ccsr_ssi { | |||
196 | #define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT) | 196 | #define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT) |
197 | #define CCSR_SSI_SOR_SYNRST 0x00000001 | 197 | #define CCSR_SSI_SOR_SYNRST 0x00000001 |
198 | 198 | ||
199 | #define CCSR_SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5) | ||
200 | #define CCSR_SSI_SACNT_WR 0x00000010 | ||
201 | #define CCSR_SSI_SACNT_RD 0x00000008 | ||
202 | #define CCSR_SSI_SACNT_RDWR_MASK 0x00000018 | ||
203 | #define CCSR_SSI_SACNT_TIF 0x00000004 | ||
204 | #define CCSR_SSI_SACNT_FV 0x00000002 | ||
205 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 | ||
206 | |||
199 | #endif | 207 | #endif |
200 | 208 | ||
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index 3f333e5b4673..47f046a8fdab 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c | |||
@@ -262,7 +262,7 @@ static int imx_audmux_probe(struct platform_device *pdev) | |||
262 | return PTR_ERR(pinctrl); | 262 | return PTR_ERR(pinctrl); |
263 | } | 263 | } |
264 | 264 | ||
265 | audmux_clk = clk_get(&pdev->dev, "audmux"); | 265 | audmux_clk = devm_clk_get(&pdev->dev, "audmux"); |
266 | if (IS_ERR(audmux_clk)) { | 266 | if (IS_ERR(audmux_clk)) { |
267 | dev_dbg(&pdev->dev, "cannot get clock: %ld\n", | 267 | dev_dbg(&pdev->dev, "cannot get clock: %ld\n", |
268 | PTR_ERR(audmux_clk)); | 268 | PTR_ERR(audmux_clk)); |
@@ -282,7 +282,6 @@ static int imx_audmux_remove(struct platform_device *pdev) | |||
282 | { | 282 | { |
283 | if (audmux_type == IMX31_AUDMUX) | 283 | if (audmux_type == IMX31_AUDMUX) |
284 | audmux_debugfs_remove(); | 284 | audmux_debugfs_remove(); |
285 | clk_put(audmux_clk); | ||
286 | 285 | ||
287 | return 0; | 286 | return 0; |
288 | } | 287 | } |
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 500f8ce55d78..c246fb514930 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c | |||
@@ -11,74 +11,30 @@ | |||
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
22 | #include <linux/slab.h> | ||
23 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
24 | #include <linux/types.h> | 16 | #include <linux/types.h> |
25 | 17 | ||
26 | #include <sound/core.h> | 18 | #include <sound/core.h> |
27 | #include <sound/initval.h> | ||
28 | #include <sound/pcm.h> | 19 | #include <sound/pcm.h> |
29 | #include <sound/pcm_params.h> | ||
30 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
31 | #include <sound/dmaengine_pcm.h> | 21 | #include <sound/dmaengine_pcm.h> |
32 | 22 | ||
33 | #include <linux/platform_data/dma-imx.h> | ||
34 | |||
35 | #include "imx-pcm.h" | 23 | #include "imx-pcm.h" |
36 | 24 | ||
37 | static bool filter(struct dma_chan *chan, void *param) | 25 | static bool filter(struct dma_chan *chan, void *param) |
38 | { | 26 | { |
27 | struct snd_dmaengine_dai_dma_data *dma_data = param; | ||
28 | |||
39 | if (!imx_dma_is_general_purpose(chan)) | 29 | if (!imx_dma_is_general_purpose(chan)) |
40 | return false; | 30 | return false; |
41 | 31 | ||
42 | chan->private = param; | 32 | chan->private = dma_data->filter_data; |
43 | 33 | ||
44 | return true; | 34 | return true; |
45 | } | 35 | } |
46 | 36 | ||
47 | static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, | 37 | static const struct snd_pcm_hardware imx_pcm_hardware = { |
48 | struct snd_pcm_hw_params *params) | ||
49 | { | ||
50 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
51 | struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); | ||
52 | struct imx_pcm_dma_params *dma_params; | ||
53 | struct dma_slave_config slave_config; | ||
54 | int ret; | ||
55 | |||
56 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
57 | |||
58 | ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); | ||
59 | if (ret) | ||
60 | return ret; | ||
61 | |||
62 | slave_config.device_fc = false; | ||
63 | |||
64 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
65 | slave_config.dst_addr = dma_params->dma_addr; | ||
66 | slave_config.dst_maxburst = dma_params->burstsize; | ||
67 | } else { | ||
68 | slave_config.src_addr = dma_params->dma_addr; | ||
69 | slave_config.src_maxburst = dma_params->burstsize; | ||
70 | } | ||
71 | |||
72 | ret = dmaengine_slave_config(chan, &slave_config); | ||
73 | if (ret) | ||
74 | return ret; | ||
75 | |||
76 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static struct snd_pcm_hardware snd_imx_hardware = { | ||
82 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 38 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
83 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 39 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
84 | SNDRV_PCM_INFO_MMAP | | 40 | SNDRV_PCM_INFO_MMAP | |
@@ -97,64 +53,22 @@ static struct snd_pcm_hardware snd_imx_hardware = { | |||
97 | .fifo_size = 0, | 53 | .fifo_size = 0, |
98 | }; | 54 | }; |
99 | 55 | ||
100 | static int snd_imx_open(struct snd_pcm_substream *substream) | 56 | static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = { |
101 | { | 57 | .pcm_hardware = &imx_pcm_hardware, |
102 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 58 | .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, |
103 | struct imx_pcm_dma_params *dma_params; | 59 | .compat_filter_fn = filter, |
104 | struct imx_dma_data *dma_data; | 60 | .prealloc_buffer_size = IMX_SSI_DMABUF_SIZE, |
105 | int ret; | 61 | }; |
106 | |||
107 | snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); | ||
108 | |||
109 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
110 | |||
111 | dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); | ||
112 | if (!dma_data) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | dma_data->peripheral_type = dma_params->shared_peripheral ? | ||
116 | IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI; | ||
117 | dma_data->priority = DMA_PRIO_HIGH; | ||
118 | dma_data->dma_request = dma_params->dma; | ||
119 | |||
120 | ret = snd_dmaengine_pcm_open(substream, filter, dma_data); | ||
121 | if (ret) { | ||
122 | kfree(dma_data); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | snd_dmaengine_pcm_set_data(substream, dma_data); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | 62 | ||
131 | static int snd_imx_close(struct snd_pcm_substream *substream) | 63 | int imx_pcm_dma_init(struct platform_device *pdev) |
132 | { | 64 | { |
133 | struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); | 65 | return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, |
134 | 66 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | |
135 | snd_dmaengine_pcm_close(substream); | 67 | SND_DMAENGINE_PCM_FLAG_NO_DT | |
136 | kfree(dma_data); | 68 | SND_DMAENGINE_PCM_FLAG_COMPAT); |
137 | |||
138 | return 0; | ||
139 | } | 69 | } |
140 | 70 | ||
141 | static struct snd_pcm_ops imx_pcm_ops = { | 71 | void imx_pcm_dma_exit(struct platform_device *pdev) |
142 | .open = snd_imx_open, | ||
143 | .close = snd_imx_close, | ||
144 | .ioctl = snd_pcm_lib_ioctl, | ||
145 | .hw_params = snd_imx_pcm_hw_params, | ||
146 | .trigger = snd_dmaengine_pcm_trigger, | ||
147 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
148 | .mmap = snd_imx_pcm_mmap, | ||
149 | }; | ||
150 | |||
151 | static struct snd_soc_platform_driver imx_soc_platform_mx2 = { | ||
152 | .ops = &imx_pcm_ops, | ||
153 | .pcm_new = imx_pcm_new, | ||
154 | .pcm_free = imx_pcm_free, | ||
155 | }; | ||
156 | |||
157 | int imx_pcm_dma_init(struct platform_device *pdev) | ||
158 | { | 72 | { |
159 | return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); | 73 | snd_dmaengine_pcm_unregister(&pdev->dev); |
160 | } | 74 | } |
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 920f945cb2f4..670b96b0ce2f 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "imx-ssi.h" | 34 | #include "imx-ssi.h" |
35 | 35 | ||
36 | struct imx_pcm_runtime_data { | 36 | struct imx_pcm_runtime_data { |
37 | int period; | 37 | unsigned int period; |
38 | int periods; | 38 | int periods; |
39 | unsigned long offset; | 39 | unsigned long offset; |
40 | unsigned long last_offset; | 40 | unsigned long last_offset; |
@@ -299,8 +299,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev) | |||
299 | 299 | ||
300 | imx_ssi_fiq_base = (unsigned long)ssi->base; | 300 | imx_ssi_fiq_base = (unsigned long)ssi->base; |
301 | 301 | ||
302 | ssi->dma_params_tx.burstsize = 4; | 302 | ssi->dma_params_tx.maxburst = 4; |
303 | ssi->dma_params_rx.burstsize = 6; | 303 | ssi->dma_params_rx.maxburst = 6; |
304 | 304 | ||
305 | ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); | 305 | ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); |
306 | if (ret) | 306 | if (ret) |
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index 0d0625bfcb65..c49896442d8e 100644 --- a/sound/soc/fsl/imx-pcm.c +++ b/sound/soc/fsl/imx-pcm.c | |||
@@ -114,7 +114,11 @@ static int imx_pcm_probe(struct platform_device *pdev) | |||
114 | 114 | ||
115 | static int imx_pcm_remove(struct platform_device *pdev) | 115 | static int imx_pcm_remove(struct platform_device *pdev) |
116 | { | 116 | { |
117 | snd_soc_unregister_platform(&pdev->dev); | 117 | if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0) |
118 | snd_soc_unregister_platform(&pdev->dev); | ||
119 | else | ||
120 | imx_pcm_dma_exit(pdev); | ||
121 | |||
118 | return 0; | 122 | return 0; |
119 | } | 123 | } |
120 | 124 | ||
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 5ae13a13a353..b7fa0d75c687 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h | |||
@@ -13,17 +13,24 @@ | |||
13 | #ifndef _IMX_PCM_H | 13 | #ifndef _IMX_PCM_H |
14 | #define _IMX_PCM_H | 14 | #define _IMX_PCM_H |
15 | 15 | ||
16 | #include <linux/platform_data/dma-imx.h> | ||
17 | |||
16 | /* | 18 | /* |
17 | * Do not change this as the FIQ handler depends on this size | 19 | * Do not change this as the FIQ handler depends on this size |
18 | */ | 20 | */ |
19 | #define IMX_SSI_DMABUF_SIZE (64 * 1024) | 21 | #define IMX_SSI_DMABUF_SIZE (64 * 1024) |
20 | 22 | ||
21 | struct imx_pcm_dma_params { | 23 | static inline void |
22 | int dma; | 24 | imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data, |
23 | unsigned long dma_addr; | 25 | int dma, bool shared) |
24 | int burstsize; | 26 | { |
25 | bool shared_peripheral; /* The peripheral is on SPBA bus */ | 27 | dma_data->dma_request = dma; |
26 | }; | 28 | dma_data->priority = DMA_PRIO_HIGH; |
29 | if (shared) | ||
30 | dma_data->peripheral_type = IMX_DMATYPE_SSI_SP; | ||
31 | else | ||
32 | dma_data->peripheral_type = IMX_DMATYPE_SSI; | ||
33 | } | ||
27 | 34 | ||
28 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | 35 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, |
29 | struct vm_area_struct *vma); | 36 | struct vm_area_struct *vma); |
@@ -32,11 +39,16 @@ void imx_pcm_free(struct snd_pcm *pcm); | |||
32 | 39 | ||
33 | #ifdef CONFIG_SND_SOC_IMX_PCM_DMA | 40 | #ifdef CONFIG_SND_SOC_IMX_PCM_DMA |
34 | int imx_pcm_dma_init(struct platform_device *pdev); | 41 | int imx_pcm_dma_init(struct platform_device *pdev); |
42 | void imx_pcm_dma_exit(struct platform_device *pdev); | ||
35 | #else | 43 | #else |
36 | static inline int imx_pcm_dma_init(struct platform_device *pdev) | 44 | static inline int imx_pcm_dma_init(struct platform_device *pdev) |
37 | { | 45 | { |
38 | return -ENODEV; | 46 | return -ENODEV; |
39 | } | 47 | } |
48 | |||
49 | static inline void imx_pcm_dma_exit(struct platform_device *pdev) | ||
50 | { | ||
51 | } | ||
40 | #endif | 52 | #endif |
41 | 53 | ||
42 | #ifdef CONFIG_SND_SOC_IMX_PCM_FIQ | 54 | #ifdef CONFIG_SND_SOC_IMX_PCM_FIQ |
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 424347e9b2d7..9584e78858df 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c | |||
@@ -148,7 +148,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) | |||
148 | data->dai.stream_name = "HiFi"; | 148 | data->dai.stream_name = "HiFi"; |
149 | data->dai.codec_dai_name = "sgtl5000"; | 149 | data->dai.codec_dai_name = "sgtl5000"; |
150 | data->dai.codec_of_node = codec_np; | 150 | data->dai.codec_of_node = codec_np; |
151 | data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev); | 151 | data->dai.cpu_of_node = ssi_np; |
152 | data->dai.platform_name = "imx-pcm-audio"; | 152 | data->dai.platform_name = "imx-pcm-audio"; |
153 | data->dai.init = &imx_sgtl5000_dai_init; | 153 | data->dai.init = &imx_sgtl5000_dai_init; |
154 | data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 154 | data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 810c7eeb7b03..902fab02b851 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
@@ -232,23 +232,6 @@ static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, | |||
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | 234 | ||
235 | static int imx_ssi_startup(struct snd_pcm_substream *substream, | ||
236 | struct snd_soc_dai *cpu_dai) | ||
237 | { | ||
238 | struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); | ||
239 | struct imx_pcm_dma_params *dma_data; | ||
240 | |||
241 | /* Tx/Rx config */ | ||
242 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
243 | dma_data = &ssi->dma_params_tx; | ||
244 | else | ||
245 | dma_data = &ssi->dma_params_rx; | ||
246 | |||
247 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | 235 | /* |
253 | * Should only be called when port is inactive (i.e. SSIEN = 0), | 236 | * Should only be called when port is inactive (i.e. SSIEN = 0), |
254 | * although can be called multiple times by upper layers. | 237 | * although can be called multiple times by upper layers. |
@@ -353,7 +336,6 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
353 | } | 336 | } |
354 | 337 | ||
355 | static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { | 338 | static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { |
356 | .startup = imx_ssi_startup, | ||
357 | .hw_params = imx_ssi_hw_params, | 339 | .hw_params = imx_ssi_hw_params, |
358 | .set_fmt = imx_ssi_set_dai_fmt, | 340 | .set_fmt = imx_ssi_set_dai_fmt, |
359 | .set_clkdiv = imx_ssi_set_dai_clkdiv, | 341 | .set_clkdiv = imx_ssi_set_dai_clkdiv, |
@@ -369,10 +351,14 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) | |||
369 | 351 | ||
370 | snd_soc_dai_set_drvdata(dai, ssi); | 352 | snd_soc_dai_set_drvdata(dai, ssi); |
371 | 353 | ||
372 | val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | | 354 | val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.maxburst) | |
373 | SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); | 355 | SSI_SFCSR_RFWM0(ssi->dma_params_rx.maxburst); |
374 | writel(val, ssi->base + SSI_SFCSR); | 356 | writel(val, ssi->base + SSI_SFCSR); |
375 | 357 | ||
358 | /* Tx/Rx config */ | ||
359 | dai->playback_dma_data = &ssi->dma_params_tx; | ||
360 | dai->capture_dma_data = &ssi->dma_params_rx; | ||
361 | |||
376 | return 0; | 362 | return 0; |
377 | } | 363 | } |
378 | 364 | ||
@@ -400,7 +386,7 @@ static struct snd_soc_dai_driver imx_ac97_dai = { | |||
400 | .stream_name = "AC97 Playback", | 386 | .stream_name = "AC97 Playback", |
401 | .channels_min = 2, | 387 | .channels_min = 2, |
402 | .channels_max = 2, | 388 | .channels_max = 2, |
403 | .rates = SNDRV_PCM_RATE_48000, | 389 | .rates = SNDRV_PCM_RATE_8000_48000, |
404 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 390 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
405 | }, | 391 | }, |
406 | .capture = { | 392 | .capture = { |
@@ -413,6 +399,10 @@ static struct snd_soc_dai_driver imx_ac97_dai = { | |||
413 | .ops = &imx_ssi_pcm_dai_ops, | 399 | .ops = &imx_ssi_pcm_dai_ops, |
414 | }; | 400 | }; |
415 | 401 | ||
402 | static const struct snd_soc_component_driver imx_component = { | ||
403 | .name = DRV_NAME, | ||
404 | }; | ||
405 | |||
416 | static void setup_channel_to_ac97(struct imx_ssi *imx_ssi) | 406 | static void setup_channel_to_ac97(struct imx_ssi *imx_ssi) |
417 | { | 407 | { |
418 | void __iomem *base = imx_ssi->base; | 408 | void __iomem *base = imx_ssi->base; |
@@ -575,23 +565,31 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
575 | 565 | ||
576 | writel(0x0, ssi->base + SSI_SIER); | 566 | writel(0x0, ssi->base + SSI_SIER); |
577 | 567 | ||
578 | ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; | 568 | ssi->dma_params_rx.addr = res->start + SSI_SRX0; |
579 | ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; | 569 | ssi->dma_params_tx.addr = res->start + SSI_STX0; |
570 | |||
571 | ssi->dma_params_tx.maxburst = 6; | ||
572 | ssi->dma_params_rx.maxburst = 4; | ||
580 | 573 | ||
581 | ssi->dma_params_tx.burstsize = 6; | 574 | ssi->dma_params_tx.filter_data = &ssi->filter_data_tx; |
582 | ssi->dma_params_rx.burstsize = 4; | 575 | ssi->dma_params_rx.filter_data = &ssi->filter_data_rx; |
583 | 576 | ||
584 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); | 577 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); |
585 | if (res) | 578 | if (res) { |
586 | ssi->dma_params_tx.dma = res->start; | 579 | imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start, |
580 | false); | ||
581 | } | ||
587 | 582 | ||
588 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); | 583 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); |
589 | if (res) | 584 | if (res) { |
590 | ssi->dma_params_rx.dma = res->start; | 585 | imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start, |
586 | false); | ||
587 | } | ||
591 | 588 | ||
592 | platform_set_drvdata(pdev, ssi); | 589 | platform_set_drvdata(pdev, ssi); |
593 | 590 | ||
594 | ret = snd_soc_register_dai(&pdev->dev, dai); | 591 | ret = snd_soc_register_component(&pdev->dev, &imx_component, |
592 | dai, 1); | ||
595 | if (ret) { | 593 | if (ret) { |
596 | dev_err(&pdev->dev, "register DAI failed\n"); | 594 | dev_err(&pdev->dev, "register DAI failed\n"); |
597 | goto failed_register; | 595 | goto failed_register; |
@@ -632,7 +630,7 @@ failed_pdev_alloc: | |||
632 | failed_pdev_fiq_add: | 630 | failed_pdev_fiq_add: |
633 | platform_device_put(ssi->soc_platform_pdev_fiq); | 631 | platform_device_put(ssi->soc_platform_pdev_fiq); |
634 | failed_pdev_fiq_alloc: | 632 | failed_pdev_fiq_alloc: |
635 | snd_soc_unregister_dai(&pdev->dev); | 633 | snd_soc_unregister_component(&pdev->dev); |
636 | failed_register: | 634 | failed_register: |
637 | release_mem_region(res->start, resource_size(res)); | 635 | release_mem_region(res->start, resource_size(res)); |
638 | failed_get_resource: | 636 | failed_get_resource: |
@@ -650,7 +648,7 @@ static int imx_ssi_remove(struct platform_device *pdev) | |||
650 | platform_device_unregister(ssi->soc_platform_pdev); | 648 | platform_device_unregister(ssi->soc_platform_pdev); |
651 | platform_device_unregister(ssi->soc_platform_pdev_fiq); | 649 | platform_device_unregister(ssi->soc_platform_pdev_fiq); |
652 | 650 | ||
653 | snd_soc_unregister_dai(&pdev->dev); | 651 | snd_soc_unregister_component(&pdev->dev); |
654 | 652 | ||
655 | if (ssi->flags & IMX_SSI_USE_AC97) | 653 | if (ssi->flags & IMX_SSI_USE_AC97) |
656 | ac97_ssi = NULL; | 654 | ac97_ssi = NULL; |
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h index dc114bdedce5..bb6b3dbb13fd 100644 --- a/sound/soc/fsl/imx-ssi.h +++ b/sound/soc/fsl/imx-ssi.h | |||
@@ -187,6 +187,7 @@ | |||
187 | 187 | ||
188 | #include <linux/dmaengine.h> | 188 | #include <linux/dmaengine.h> |
189 | #include <linux/platform_data/dma-imx.h> | 189 | #include <linux/platform_data/dma-imx.h> |
190 | #include <sound/dmaengine_pcm.h> | ||
190 | #include "imx-pcm.h" | 191 | #include "imx-pcm.h" |
191 | 192 | ||
192 | struct imx_ssi { | 193 | struct imx_ssi { |
@@ -204,8 +205,10 @@ struct imx_ssi { | |||
204 | void (*ac97_reset) (struct snd_ac97 *ac97); | 205 | void (*ac97_reset) (struct snd_ac97 *ac97); |
205 | void (*ac97_warm_reset)(struct snd_ac97 *ac97); | 206 | void (*ac97_warm_reset)(struct snd_ac97 *ac97); |
206 | 207 | ||
207 | struct imx_pcm_dma_params dma_params_rx; | 208 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
208 | struct imx_pcm_dma_params dma_params_tx; | 209 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
210 | struct imx_dma_data filter_data_tx; | ||
211 | struct imx_dma_data filter_data_rx; | ||
209 | 212 | ||
210 | int enabled; | 213 | int enabled; |
211 | 214 | ||
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index a4aec0488dd3..4141b35ef0bb 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
@@ -270,6 +270,9 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = { | |||
270 | .ops = &psc_ac97_digital_ops, | 270 | .ops = &psc_ac97_digital_ops, |
271 | } }; | 271 | } }; |
272 | 272 | ||
273 | static const struct snd_soc_component_driver psc_ac97_component = { | ||
274 | .name = DRV_NAME, | ||
275 | }; | ||
273 | 276 | ||
274 | 277 | ||
275 | /* --------------------------------------------------------------------- | 278 | /* --------------------------------------------------------------------- |
@@ -287,7 +290,8 @@ static int psc_ac97_of_probe(struct platform_device *op) | |||
287 | if (rc != 0) | 290 | if (rc != 0) |
288 | return rc; | 291 | return rc; |
289 | 292 | ||
290 | rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); | 293 | rc = snd_soc_register_component(&op->dev, &psc_ac97_component, |
294 | psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); | ||
291 | if (rc != 0) { | 295 | if (rc != 0) { |
292 | dev_err(&op->dev, "Failed to register DAI\n"); | 296 | dev_err(&op->dev, "Failed to register DAI\n"); |
293 | return rc; | 297 | return rc; |
@@ -313,7 +317,7 @@ static int psc_ac97_of_probe(struct platform_device *op) | |||
313 | static int psc_ac97_of_remove(struct platform_device *op) | 317 | static int psc_ac97_of_remove(struct platform_device *op) |
314 | { | 318 | { |
315 | mpc5200_audio_dma_destroy(op); | 319 | mpc5200_audio_dma_destroy(op); |
316 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); | 320 | snd_soc_unregister_component(&op->dev); |
317 | return 0; | 321 | return 0; |
318 | } | 322 | } |
319 | 323 | ||
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index b95b966f25a0..f4efaadb80a2 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c | |||
@@ -148,6 +148,10 @@ static struct snd_soc_dai_driver psc_i2s_dai[] = {{ | |||
148 | .ops = &psc_i2s_dai_ops, | 148 | .ops = &psc_i2s_dai_ops, |
149 | } }; | 149 | } }; |
150 | 150 | ||
151 | static const struct snd_soc_component_driver psc_i2s_component = { | ||
152 | .name = "mpc5200-i2s", | ||
153 | }; | ||
154 | |||
151 | /* --------------------------------------------------------------------- | 155 | /* --------------------------------------------------------------------- |
152 | * OF platform bus binding code: | 156 | * OF platform bus binding code: |
153 | * - Probe/remove operations | 157 | * - Probe/remove operations |
@@ -163,7 +167,8 @@ static int psc_i2s_of_probe(struct platform_device *op) | |||
163 | if (rc != 0) | 167 | if (rc != 0) |
164 | return rc; | 168 | return rc; |
165 | 169 | ||
166 | rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); | 170 | rc = snd_soc_register_component(&op->dev, &psc_i2s_component, |
171 | psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); | ||
167 | if (rc != 0) { | 172 | if (rc != 0) { |
168 | pr_err("Failed to register DAI\n"); | 173 | pr_err("Failed to register DAI\n"); |
169 | return rc; | 174 | return rc; |
@@ -208,7 +213,7 @@ static int psc_i2s_of_probe(struct platform_device *op) | |||
208 | static int psc_i2s_of_remove(struct platform_device *op) | 213 | static int psc_i2s_of_remove(struct platform_device *op) |
209 | { | 214 | { |
210 | mpc5200_audio_dma_destroy(op); | 215 | mpc5200_audio_dma_destroy(op); |
211 | snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); | 216 | snd_soc_unregister_component(&op->dev); |
212 | return 0; | 217 | return 0; |
213 | } | 218 | } |
214 | 219 | ||
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 6cef491f4823..9a126441c5f3 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c | |||
@@ -425,6 +425,10 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { | |||
425 | .resume = jz4740_i2s_resume, | 425 | .resume = jz4740_i2s_resume, |
426 | }; | 426 | }; |
427 | 427 | ||
428 | static const struct snd_soc_component_driver jz4740_i2s_component = { | ||
429 | .name = "jz4740-i2s", | ||
430 | }; | ||
431 | |||
428 | static int jz4740_i2s_dev_probe(struct platform_device *pdev) | 432 | static int jz4740_i2s_dev_probe(struct platform_device *pdev) |
429 | { | 433 | { |
430 | struct jz4740_i2s *i2s; | 434 | struct jz4740_i2s *i2s; |
@@ -469,7 +473,8 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev) | |||
469 | } | 473 | } |
470 | 474 | ||
471 | platform_set_drvdata(pdev, i2s); | 475 | platform_set_drvdata(pdev, i2s); |
472 | ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai); | 476 | ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component, |
477 | &jz4740_i2s_dai, 1); | ||
473 | 478 | ||
474 | if (ret) { | 479 | if (ret) { |
475 | dev_err(&pdev->dev, "Failed to register DAI\n"); | 480 | dev_err(&pdev->dev, "Failed to register DAI\n"); |
@@ -496,7 +501,7 @@ static int jz4740_i2s_dev_remove(struct platform_device *pdev) | |||
496 | { | 501 | { |
497 | struct jz4740_i2s *i2s = platform_get_drvdata(pdev); | 502 | struct jz4740_i2s *i2s = platform_get_drvdata(pdev); |
498 | 503 | ||
499 | snd_soc_unregister_dai(&pdev->dev); | 504 | snd_soc_unregister_component(&pdev->dev); |
500 | 505 | ||
501 | clk_put(i2s->clk_i2s); | 506 | clk_put(i2s->clk_i2s); |
502 | clk_put(i2s->clk_aic); | 507 | clk_put(i2s->clk_aic); |
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index c74c89065493..befe68f59285 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c | |||
@@ -451,6 +451,10 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { | |||
451 | .ops = &kirkwood_i2s_dai_ops, | 451 | .ops = &kirkwood_i2s_dai_ops, |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static const struct snd_soc_component_driver kirkwood_i2s_component = { | ||
455 | .name = DRV_NAME, | ||
456 | }; | ||
457 | |||
454 | static int kirkwood_i2s_dev_probe(struct platform_device *pdev) | 458 | static int kirkwood_i2s_dev_probe(struct platform_device *pdev) |
455 | { | 459 | { |
456 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; | 460 | struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
@@ -524,10 +528,11 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) | |||
524 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; | 528 | priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; |
525 | } | 529 | } |
526 | 530 | ||
527 | err = snd_soc_register_dai(&pdev->dev, soc_dai); | 531 | err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, |
532 | soc_dai, 1); | ||
528 | if (!err) | 533 | if (!err) |
529 | return 0; | 534 | return 0; |
530 | dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); | 535 | dev_err(&pdev->dev, "snd_soc_register_component failed\n"); |
531 | 536 | ||
532 | if (!IS_ERR(priv->extclk)) { | 537 | if (!IS_ERR(priv->extclk)) { |
533 | clk_disable_unprepare(priv->extclk); | 538 | clk_disable_unprepare(priv->extclk); |
@@ -542,7 +547,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev) | |||
542 | { | 547 | { |
543 | struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); | 548 | struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); |
544 | 549 | ||
545 | snd_soc_unregister_dai(&pdev->dev); | 550 | snd_soc_unregister_component(&pdev->dev); |
546 | 551 | ||
547 | if (!IS_ERR(priv->extclk)) { | 552 | if (!IS_ERR(priv->extclk)) { |
548 | clk_disable_unprepare(priv->extclk); | 553 | clk_disable_unprepare(priv->extclk); |
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index a263cbed8624..392fc0b8f5b8 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * sst_platform.c - Intel MID Platform driver | 2 | * sst_platform.c - Intel MID Platform driver |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2012 Intel Corp | 4 | * Copyright (C) 2010-2013 Intel Corp |
5 | * Author: Vinod Koul <vinod.koul@intel.com> | 5 | * Author: Vinod Koul <vinod.koul@intel.com> |
6 | * Author: Harsha Priya <priya.harsha@intel.com> | 6 | * Author: Harsha Priya <priya.harsha@intel.com> |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
@@ -165,6 +165,10 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
165 | }, | 165 | }, |
166 | }; | 166 | }; |
167 | 167 | ||
168 | static const struct snd_soc_component_driver sst_component = { | ||
169 | .name = "sst", | ||
170 | }; | ||
171 | |||
168 | /* helper functions */ | 172 | /* helper functions */ |
169 | static inline void sst_set_stream_status(struct sst_runtime_stream *stream, | 173 | static inline void sst_set_stream_status(struct sst_runtime_stream *stream, |
170 | int state) | 174 | int state) |
@@ -652,11 +656,21 @@ static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | |||
652 | return stream->compr_ops->get_codec_caps(codec); | 656 | return stream->compr_ops->get_codec_caps(codec); |
653 | } | 657 | } |
654 | 658 | ||
659 | static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, | ||
660 | struct snd_compr_metadata *metadata) | ||
661 | { | ||
662 | struct sst_runtime_stream *stream = | ||
663 | cstream->runtime->private_data; | ||
664 | |||
665 | return stream->compr_ops->set_metadata(stream->id, metadata); | ||
666 | } | ||
667 | |||
655 | static struct snd_compr_ops sst_platform_compr_ops = { | 668 | static struct snd_compr_ops sst_platform_compr_ops = { |
656 | 669 | ||
657 | .open = sst_platform_compr_open, | 670 | .open = sst_platform_compr_open, |
658 | .free = sst_platform_compr_free, | 671 | .free = sst_platform_compr_free, |
659 | .set_params = sst_platform_compr_set_params, | 672 | .set_params = sst_platform_compr_set_params, |
673 | .set_metadata = sst_platform_compr_set_metadata, | ||
660 | .trigger = sst_platform_compr_trigger, | 674 | .trigger = sst_platform_compr_trigger, |
661 | .pointer = sst_platform_compr_pointer, | 675 | .pointer = sst_platform_compr_pointer, |
662 | .ack = sst_platform_compr_ack, | 676 | .ack = sst_platform_compr_ack, |
@@ -683,7 +697,7 @@ static int sst_platform_probe(struct platform_device *pdev) | |||
683 | return ret; | 697 | return ret; |
684 | } | 698 | } |
685 | 699 | ||
686 | ret = snd_soc_register_dais(&pdev->dev, | 700 | ret = snd_soc_register_component(&pdev->dev, &sst_component, |
687 | sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); | 701 | sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); |
688 | if (ret) { | 702 | if (ret) { |
689 | pr_err("registering cpu dais failed\n"); | 703 | pr_err("registering cpu dais failed\n"); |
@@ -695,7 +709,7 @@ static int sst_platform_probe(struct platform_device *pdev) | |||
695 | static int sst_platform_remove(struct platform_device *pdev) | 709 | static int sst_platform_remove(struct platform_device *pdev) |
696 | { | 710 | { |
697 | 711 | ||
698 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai)); | 712 | snd_soc_unregister_component(&pdev->dev); |
699 | snd_soc_unregister_platform(&pdev->dev); | 713 | snd_soc_unregister_platform(&pdev->dev); |
700 | pr_debug("sst_platform_remove success\n"); | 714 | pr_debug("sst_platform_remove success\n"); |
701 | return 0; | 715 | return 0; |
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index d61c5d514ffa..cacc9066ec52 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h | |||
@@ -124,6 +124,8 @@ struct compress_sst_ops { | |||
124 | int (*close) (unsigned int str_id); | 124 | int (*close) (unsigned int str_id); |
125 | int (*get_caps) (struct snd_compr_caps *caps); | 125 | int (*get_caps) (struct snd_compr_caps *caps); |
126 | int (*get_codec_caps) (struct snd_compr_codec_caps *codec); | 126 | int (*get_codec_caps) (struct snd_compr_codec_caps *codec); |
127 | int (*set_metadata) (unsigned int str_id, | ||
128 | struct snd_compr_metadata *mdata); | ||
127 | 129 | ||
128 | }; | 130 | }; |
129 | 131 | ||
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index b6fa77678d97..78d321cbe8b4 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | menuconfig SND_MXS_SOC | 1 | menuconfig SND_MXS_SOC |
2 | tristate "SoC Audio for Freescale MXS CPUs" | 2 | tristate "SoC Audio for Freescale MXS CPUs" |
3 | depends on ARCH_MXS | 3 | depends on ARCH_MXS |
4 | select SND_SOC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the MXS SAIF interface. | 7 | the MXS SAIF interface. |
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 564b5b60319d..b41fffc056fb 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c | |||
@@ -18,38 +18,24 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/device.h> | 21 | #include <linux/device.h> |
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/init.h> | 22 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/module.h> | 23 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/dmaengine.h> | ||
31 | #include <linux/fsl/mxs-dma.h> | ||
32 | 24 | ||
33 | #include <sound/core.h> | 25 | #include <sound/core.h> |
34 | #include <sound/initval.h> | ||
35 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
36 | #include <sound/pcm_params.h> | ||
37 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
38 | #include <sound/dmaengine_pcm.h> | 28 | #include <sound/dmaengine_pcm.h> |
39 | 29 | ||
40 | #include "mxs-pcm.h" | 30 | #include "mxs-pcm.h" |
41 | 31 | ||
42 | struct mxs_pcm_dma_data { | 32 | static const struct snd_pcm_hardware snd_mxs_hardware = { |
43 | struct mxs_dma_data dma_data; | ||
44 | struct mxs_pcm_dma_params *dma_params; | ||
45 | }; | ||
46 | |||
47 | static struct snd_pcm_hardware snd_mxs_hardware = { | ||
48 | .info = SNDRV_PCM_INFO_MMAP | | 33 | .info = SNDRV_PCM_INFO_MMAP | |
49 | SNDRV_PCM_INFO_MMAP_VALID | | 34 | SNDRV_PCM_INFO_MMAP_VALID | |
50 | SNDRV_PCM_INFO_PAUSE | | 35 | SNDRV_PCM_INFO_PAUSE | |
51 | SNDRV_PCM_INFO_RESUME | | 36 | SNDRV_PCM_INFO_RESUME | |
52 | SNDRV_PCM_INFO_INTERLEAVED, | 37 | SNDRV_PCM_INFO_INTERLEAVED | |
38 | SNDRV_PCM_INFO_HALF_DUPLEX, | ||
53 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 39 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
54 | SNDRV_PCM_FMTBIT_S20_3LE | | 40 | SNDRV_PCM_FMTBIT_S20_3LE | |
55 | SNDRV_PCM_FMTBIT_S24_LE, | 41 | SNDRV_PCM_FMTBIT_S24_LE, |
@@ -61,13 +47,11 @@ static struct snd_pcm_hardware snd_mxs_hardware = { | |||
61 | .periods_max = 52, | 47 | .periods_max = 52, |
62 | .buffer_bytes_max = 64 * 1024, | 48 | .buffer_bytes_max = 64 * 1024, |
63 | .fifo_size = 32, | 49 | .fifo_size = 32, |
64 | |||
65 | }; | 50 | }; |
66 | 51 | ||
67 | static bool filter(struct dma_chan *chan, void *param) | 52 | static bool filter(struct dma_chan *chan, void *param) |
68 | { | 53 | { |
69 | struct mxs_pcm_dma_data *pcm_dma_data = param; | 54 | struct mxs_pcm_dma_params *dma_params = param; |
70 | struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params; | ||
71 | 55 | ||
72 | if (!mxs_dma_is_apbx(chan)) | 56 | if (!mxs_dma_is_apbx(chan)) |
73 | return false; | 57 | return false; |
@@ -75,160 +59,30 @@ static bool filter(struct dma_chan *chan, void *param) | |||
75 | if (chan->chan_id != dma_params->chan_num) | 59 | if (chan->chan_id != dma_params->chan_num) |
76 | return false; | 60 | return false; |
77 | 61 | ||
78 | chan->private = &pcm_dma_data->dma_data; | 62 | chan->private = &dma_params->dma_data; |
79 | 63 | ||
80 | return true; | 64 | return true; |
81 | } | 65 | } |
82 | 66 | ||
83 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, | 67 | static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { |
84 | struct snd_pcm_hw_params *params) | 68 | .pcm_hardware = &snd_mxs_hardware, |
85 | { | 69 | .compat_filter_fn = filter, |
86 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 70 | .prealloc_buffer_size = 64 * 1024, |
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int snd_mxs_open(struct snd_pcm_substream *substream) | ||
92 | { | ||
93 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
94 | struct mxs_pcm_dma_data *pcm_dma_data; | ||
95 | int ret; | ||
96 | |||
97 | pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL); | ||
98 | if (pcm_dma_data == NULL) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
102 | pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq; | ||
103 | |||
104 | ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data); | ||
105 | if (ret) { | ||
106 | kfree(pcm_dma_data); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); | ||
111 | |||
112 | snd_dmaengine_pcm_set_data(substream, pcm_dma_data); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int snd_mxs_close(struct snd_pcm_substream *substream) | ||
118 | { | ||
119 | struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream); | ||
120 | |||
121 | snd_dmaengine_pcm_close(substream); | ||
122 | kfree(pcm_dma_data); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, | ||
128 | struct vm_area_struct *vma) | ||
129 | { | ||
130 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
131 | |||
132 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
133 | runtime->dma_area, | ||
134 | runtime->dma_addr, | ||
135 | runtime->dma_bytes); | ||
136 | } | ||
137 | |||
138 | static struct snd_pcm_ops mxs_pcm_ops = { | ||
139 | .open = snd_mxs_open, | ||
140 | .close = snd_mxs_close, | ||
141 | .ioctl = snd_pcm_lib_ioctl, | ||
142 | .hw_params = snd_mxs_pcm_hw_params, | ||
143 | .trigger = snd_dmaengine_pcm_trigger, | ||
144 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
145 | .mmap = snd_mxs_pcm_mmap, | ||
146 | }; | ||
147 | |||
148 | static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
149 | { | ||
150 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
151 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
152 | size_t size = snd_mxs_hardware.buffer_bytes_max; | ||
153 | |||
154 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
155 | buf->dev.dev = pcm->card->dev; | ||
156 | buf->private_data = NULL; | ||
157 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
158 | &buf->addr, GFP_KERNEL); | ||
159 | if (!buf->area) | ||
160 | return -ENOMEM; | ||
161 | buf->bytes = size; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32); | ||
167 | static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
168 | { | ||
169 | struct snd_card *card = rtd->card->snd_card; | ||
170 | struct snd_pcm *pcm = rtd->pcm; | ||
171 | int ret = 0; | ||
172 | |||
173 | if (!card->dev->dma_mask) | ||
174 | card->dev->dma_mask = &mxs_pcm_dmamask; | ||
175 | if (!card->dev->coherent_dma_mask) | ||
176 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
177 | |||
178 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
179 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
180 | SNDRV_PCM_STREAM_PLAYBACK); | ||
181 | if (ret) | ||
182 | goto out; | ||
183 | } | ||
184 | |||
185 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
186 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
187 | SNDRV_PCM_STREAM_CAPTURE); | ||
188 | if (ret) | ||
189 | goto out; | ||
190 | } | ||
191 | |||
192 | out: | ||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | static void mxs_pcm_free(struct snd_pcm *pcm) | ||
197 | { | ||
198 | struct snd_pcm_substream *substream; | ||
199 | struct snd_dma_buffer *buf; | ||
200 | int stream; | ||
201 | |||
202 | for (stream = 0; stream < 2; stream++) { | ||
203 | substream = pcm->streams[stream].substream; | ||
204 | if (!substream) | ||
205 | continue; | ||
206 | |||
207 | buf = &substream->dma_buffer; | ||
208 | if (!buf->area) | ||
209 | continue; | ||
210 | |||
211 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
212 | buf->area, buf->addr); | ||
213 | buf->area = NULL; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | static struct snd_soc_platform_driver mxs_soc_platform = { | ||
218 | .ops = &mxs_pcm_ops, | ||
219 | .pcm_new = mxs_pcm_new, | ||
220 | .pcm_free = mxs_pcm_free, | ||
221 | }; | 71 | }; |
222 | 72 | ||
223 | int mxs_pcm_platform_register(struct device *dev) | 73 | int mxs_pcm_platform_register(struct device *dev) |
224 | { | 74 | { |
225 | return snd_soc_register_platform(dev, &mxs_soc_platform); | 75 | return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, |
76 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
77 | SND_DMAENGINE_PCM_FLAG_NO_DT | | ||
78 | SND_DMAENGINE_PCM_FLAG_COMPAT | | ||
79 | SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); | ||
226 | } | 80 | } |
227 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); | 81 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); |
228 | 82 | ||
229 | void mxs_pcm_platform_unregister(struct device *dev) | 83 | void mxs_pcm_platform_unregister(struct device *dev) |
230 | { | 84 | { |
231 | snd_soc_unregister_platform(dev); | 85 | snd_dmaengine_pcm_unregister(dev); |
232 | } | 86 | } |
233 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); | 87 | EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); |
234 | 88 | ||
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index 35ba2ca42384..3aa918f9ed3e 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h | |||
@@ -19,8 +19,10 @@ | |||
19 | #ifndef _MXS_PCM_H | 19 | #ifndef _MXS_PCM_H |
20 | #define _MXS_PCM_H | 20 | #define _MXS_PCM_H |
21 | 21 | ||
22 | #include <linux/fsl/mxs-dma.h> | ||
23 | |||
22 | struct mxs_pcm_dma_params { | 24 | struct mxs_pcm_dma_params { |
23 | int chan_irq; | 25 | struct mxs_dma_data dma_data; |
24 | int chan_num; | 26 | int chan_num; |
25 | }; | 27 | }; |
26 | 28 | ||
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 41a6136e3535..d31dc52fa862 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -370,7 +370,6 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, | |||
370 | struct snd_soc_dai *cpu_dai) | 370 | struct snd_soc_dai *cpu_dai) |
371 | { | 371 | { |
372 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | 372 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); |
373 | snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param); | ||
374 | 373 | ||
375 | /* clear error status to 0 for each re-open */ | 374 | /* clear error status to 0 for each re-open */ |
376 | saif->fifo_underrun = 0; | 375 | saif->fifo_underrun = 0; |
@@ -606,6 +605,8 @@ static int mxs_saif_dai_probe(struct snd_soc_dai *dai) | |||
606 | struct mxs_saif *saif = dev_get_drvdata(dai->dev); | 605 | struct mxs_saif *saif = dev_get_drvdata(dai->dev); |
607 | 606 | ||
608 | snd_soc_dai_set_drvdata(dai, saif); | 607 | snd_soc_dai_set_drvdata(dai, saif); |
608 | dai->playback_dma_data = &saif->dma_param; | ||
609 | dai->capture_dma_data = &saif->dma_param; | ||
609 | 610 | ||
610 | return 0; | 611 | return 0; |
611 | } | 612 | } |
@@ -628,6 +629,10 @@ static struct snd_soc_dai_driver mxs_saif_dai = { | |||
628 | .ops = &mxs_saif_dai_ops, | 629 | .ops = &mxs_saif_dai_ops, |
629 | }; | 630 | }; |
630 | 631 | ||
632 | static const struct snd_soc_component_driver mxs_saif_component = { | ||
633 | .name = "mxs-saif", | ||
634 | }; | ||
635 | |||
631 | static irqreturn_t mxs_saif_irq(int irq, void *dev_id) | 636 | static irqreturn_t mxs_saif_irq(int irq, void *dev_id) |
632 | { | 637 | { |
633 | struct mxs_saif *saif = dev_id; | 638 | struct mxs_saif *saif = dev_id; |
@@ -754,9 +759,9 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
754 | return ret; | 759 | return ret; |
755 | } | 760 | } |
756 | 761 | ||
757 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); | 762 | saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1); |
758 | if (saif->dma_param.chan_irq < 0) { | 763 | if (saif->dma_param.dma_data.chan_irq < 0) { |
759 | ret = saif->dma_param.chan_irq; | 764 | ret = saif->dma_param.dma_data.chan_irq; |
760 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", | 765 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", |
761 | ret); | 766 | ret); |
762 | return ret; | 767 | return ret; |
@@ -764,7 +769,8 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
764 | 769 | ||
765 | platform_set_drvdata(pdev, saif); | 770 | platform_set_drvdata(pdev, saif); |
766 | 771 | ||
767 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); | 772 | ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component, |
773 | &mxs_saif_dai, 1); | ||
768 | if (ret) { | 774 | if (ret) { |
769 | dev_err(&pdev->dev, "register DAI failed\n"); | 775 | dev_err(&pdev->dev, "register DAI failed\n"); |
770 | return ret; | 776 | return ret; |
@@ -779,7 +785,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
779 | return 0; | 785 | return 0; |
780 | 786 | ||
781 | failed_pdev_alloc: | 787 | failed_pdev_alloc: |
782 | snd_soc_unregister_dai(&pdev->dev); | 788 | snd_soc_unregister_component(&pdev->dev); |
783 | 789 | ||
784 | return ret; | 790 | return ret; |
785 | } | 791 | } |
@@ -787,7 +793,7 @@ failed_pdev_alloc: | |||
787 | static int mxs_saif_remove(struct platform_device *pdev) | 793 | static int mxs_saif_remove(struct platform_device *pdev) |
788 | { | 794 | { |
789 | mxs_pcm_platform_unregister(&pdev->dev); | 795 | mxs_pcm_platform_unregister(&pdev->dev); |
790 | snd_soc_unregister_dai(&pdev->dev); | 796 | snd_soc_unregister_component(&pdev->dev); |
791 | 797 | ||
792 | return 0; | 798 | return 0; |
793 | } | 799 | } |
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index 0418467a4848..fe3285ceaf5b 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c | |||
@@ -314,6 +314,10 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = { | |||
314 | .ops = &nuc900_ac97_dai_ops, | 314 | .ops = &nuc900_ac97_dai_ops, |
315 | }; | 315 | }; |
316 | 316 | ||
317 | static const struct snd_soc_component_driver nuc900_ac97_component = { | ||
318 | .name = "nuc900-ac97", | ||
319 | }; | ||
320 | |||
317 | static int nuc900_ac97_drvprobe(struct platform_device *pdev) | 321 | static int nuc900_ac97_drvprobe(struct platform_device *pdev) |
318 | { | 322 | { |
319 | struct nuc900_audio *nuc900_audio; | 323 | struct nuc900_audio *nuc900_audio; |
@@ -361,7 +365,8 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev) | |||
361 | 365 | ||
362 | nuc900_ac97_data = nuc900_audio; | 366 | nuc900_ac97_data = nuc900_audio; |
363 | 367 | ||
364 | ret = snd_soc_register_dai(&pdev->dev, &nuc900_ac97_dai); | 368 | ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, |
369 | &nuc900_ac97_dai, 1); | ||
365 | if (ret) | 370 | if (ret) |
366 | goto out3; | 371 | goto out3; |
367 | 372 | ||
@@ -384,7 +389,7 @@ out0: | |||
384 | 389 | ||
385 | static int nuc900_ac97_drvremove(struct platform_device *pdev) | 390 | static int nuc900_ac97_drvremove(struct platform_device *pdev) |
386 | { | 391 | { |
387 | snd_soc_unregister_dai(&pdev->dev); | 392 | snd_soc_unregister_component(&pdev->dev); |
388 | 393 | ||
389 | clk_put(nuc900_ac97_data->clk); | 394 | clk_put(nuc900_ac97_data->clk); |
390 | iounmap(nuc900_ac97_data->mmio); | 395 | iounmap(nuc900_ac97_data->mmio); |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index c1900b2a6f28..994dcf345975 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 28 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
29 | 29 | ||
30 | #include "omap-mcbsp.h" | 30 | #include "omap-mcbsp.h" |
31 | #include "omap-pcm.h" | ||
32 | 31 | ||
33 | #include "../codecs/tlv320aic23.h" | 32 | #include "../codecs/tlv320aic23.h" |
34 | 33 | ||
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 2600447fa74f..629446482a91 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 36 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
37 | 37 | ||
38 | #include "omap-mcbsp.h" | 38 | #include "omap-mcbsp.h" |
39 | #include "omap-pcm.h" | ||
40 | #include "../codecs/cx20442.h" | 39 | #include "../codecs/cx20442.h" |
41 | 40 | ||
42 | 41 | ||
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 285c8368cb47..eb68c7db1cf3 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev) | |||
1018 | return -ENODEV; | 1018 | return -ENODEV; |
1019 | } | 1019 | } |
1020 | /* RX DMA request number, and port address configuration */ | 1020 | /* RX DMA request number, and port address configuration */ |
1021 | mcbsp->dma_data[1].name = "Audio Capture"; | 1021 | mcbsp->dma_req[1] = res->start; |
1022 | mcbsp->dma_data[1].dma_req = res->start; | 1022 | mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1]; |
1023 | mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); | 1023 | mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1); |
1024 | mcbsp->dma_data[1].maxburst = 4; | ||
1024 | 1025 | ||
1025 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); | 1026 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); |
1026 | if (!res) { | 1027 | if (!res) { |
@@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev) | |||
1028 | return -ENODEV; | 1029 | return -ENODEV; |
1029 | } | 1030 | } |
1030 | /* TX DMA request number, and port address configuration */ | 1031 | /* TX DMA request number, and port address configuration */ |
1031 | mcbsp->dma_data[0].name = "Audio Playback"; | 1032 | mcbsp->dma_req[0] = res->start; |
1032 | mcbsp->dma_data[0].dma_req = res->start; | 1033 | mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0]; |
1033 | mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); | 1034 | mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0); |
1035 | mcbsp->dma_data[0].maxburst = 4; | ||
1034 | 1036 | ||
1035 | mcbsp->fclk = clk_get(&pdev->dev, "fck"); | 1037 | mcbsp->fclk = clk_get(&pdev->dev, "fck"); |
1036 | if (IS_ERR(mcbsp->fclk)) { | 1038 | if (IS_ERR(mcbsp->fclk)) { |
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index f93e0b0af303..96d1b086bcf8 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h | |||
@@ -24,14 +24,14 @@ | |||
24 | #ifndef __ASOC_MCBSP_H | 24 | #ifndef __ASOC_MCBSP_H |
25 | #define __ASOC_MCBSP_H | 25 | #define __ASOC_MCBSP_H |
26 | 26 | ||
27 | #include "omap-pcm.h" | ||
28 | |||
29 | #ifdef CONFIG_ARCH_OMAP1 | 27 | #ifdef CONFIG_ARCH_OMAP1 |
30 | #define mcbsp_omap1() 1 | 28 | #define mcbsp_omap1() 1 |
31 | #else | 29 | #else |
32 | #define mcbsp_omap1() 0 | 30 | #define mcbsp_omap1() 0 |
33 | #endif | 31 | #endif |
34 | 32 | ||
33 | #include <sound/dmaengine_pcm.h> | ||
34 | |||
35 | /* McBSP register numbers. Register address offset = num * reg_step */ | 35 | /* McBSP register numbers. Register address offset = num * reg_step */ |
36 | enum { | 36 | enum { |
37 | /* Common registers */ | 37 | /* Common registers */ |
@@ -312,7 +312,8 @@ struct omap_mcbsp { | |||
312 | struct omap_mcbsp_platform_data *pdata; | 312 | struct omap_mcbsp_platform_data *pdata; |
313 | struct omap_mcbsp_st_data *st_data; | 313 | struct omap_mcbsp_st_data *st_data; |
314 | struct omap_mcbsp_reg_cfg cfg_regs; | 314 | struct omap_mcbsp_reg_cfg cfg_regs; |
315 | struct omap_pcm_dma_data dma_data[2]; | 315 | struct snd_dmaengine_dai_dma_data dma_data[2]; |
316 | unsigned int dma_req[2]; | ||
316 | int dma_op_mode; | 317 | int dma_op_mode; |
317 | u16 max_tx_thres; | 318 | u16 max_tx_thres; |
318 | u16 max_rx_thres; | 319 | u16 max_rx_thres; |
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index ee7cd53aa3ee..5e8d640d314f 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 34 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
35 | 35 | ||
36 | #include "omap-mcbsp.h" | 36 | #include "omap-mcbsp.h" |
37 | #include "omap-pcm.h" | ||
38 | 37 | ||
39 | #define N810_HEADSET_AMP_GPIO 10 | 38 | #define N810_HEADSET_AMP_GPIO 10 |
40 | #define N810_SPEAKER_AMP_GPIO 101 | 39 | #define N810_SPEAKER_AMP_GPIO 101 |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index e7d93fa412a9..70cd5c7b2e14 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -34,7 +34,6 @@ | |||
34 | 34 | ||
35 | #include "omap-dmic.h" | 35 | #include "omap-dmic.h" |
36 | #include "omap-mcpdm.h" | 36 | #include "omap-mcpdm.h" |
37 | #include "omap-pcm.h" | ||
38 | #include "../codecs/twl6040.h" | 37 | #include "../codecs/twl6040.h" |
39 | 38 | ||
40 | struct abe_twl6040 { | 39 | struct abe_twl6040 { |
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index ba49ccd9eed9..2ad0370146fd 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c | |||
@@ -39,8 +39,8 @@ | |||
39 | #include <sound/pcm_params.h> | 39 | #include <sound/pcm_params.h> |
40 | #include <sound/initval.h> | 40 | #include <sound/initval.h> |
41 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | #include <sound/dmaengine_pcm.h> | ||
42 | 43 | ||
43 | #include "omap-pcm.h" | ||
44 | #include "omap-dmic.h" | 44 | #include "omap-dmic.h" |
45 | 45 | ||
46 | struct omap_dmic { | 46 | struct omap_dmic { |
@@ -55,13 +55,9 @@ struct omap_dmic { | |||
55 | u32 ch_enabled; | 55 | u32 ch_enabled; |
56 | bool active; | 56 | bool active; |
57 | struct mutex mutex; | 57 | struct mutex mutex; |
58 | }; | ||
59 | 58 | ||
60 | /* | 59 | struct snd_dmaengine_dai_dma_data dma_data; |
61 | * Stream DMA parameters | 60 | unsigned int dma_req; |
62 | */ | ||
63 | static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { | ||
64 | .name = "DMIC capture", | ||
65 | }; | 61 | }; |
66 | 62 | ||
67 | static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) | 63 | static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) |
@@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, | |||
118 | 114 | ||
119 | mutex_unlock(&dmic->mutex); | 115 | mutex_unlock(&dmic->mutex); |
120 | 116 | ||
121 | snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); | 117 | snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); |
122 | return ret; | 118 | return ret; |
123 | } | 119 | } |
124 | 120 | ||
@@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, | |||
203 | struct snd_soc_dai *dai) | 199 | struct snd_soc_dai *dai) |
204 | { | 200 | { |
205 | struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); | 201 | struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); |
206 | struct omap_pcm_dma_data *dma_data; | 202 | struct snd_dmaengine_dai_dma_data *dma_data; |
207 | int channels; | 203 | int channels; |
208 | 204 | ||
209 | dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); | 205 | dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); |
@@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, | |||
230 | 226 | ||
231 | /* packet size is threshold * channels */ | 227 | /* packet size is threshold * channels */ |
232 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | 228 | dma_data = snd_soc_dai_get_dma_data(dai, substream); |
233 | dma_data->packet_size = dmic->threshold * channels; | 229 | dma_data->maxburst = dmic->threshold * channels; |
234 | 230 | ||
235 | return 0; | 231 | return 0; |
236 | } | 232 | } |
@@ -448,6 +444,10 @@ static struct snd_soc_dai_driver omap_dmic_dai = { | |||
448 | .ops = &omap_dmic_dai_ops, | 444 | .ops = &omap_dmic_dai_ops, |
449 | }; | 445 | }; |
450 | 446 | ||
447 | static const struct snd_soc_component_driver omap_dmic_component = { | ||
448 | .name = "omap-dmic", | ||
449 | }; | ||
450 | |||
451 | static int asoc_dmic_probe(struct platform_device *pdev) | 451 | static int asoc_dmic_probe(struct platform_device *pdev) |
452 | { | 452 | { |
453 | struct omap_dmic *dmic; | 453 | struct omap_dmic *dmic; |
@@ -476,7 +476,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) | |||
476 | ret = -ENODEV; | 476 | ret = -ENODEV; |
477 | goto err_put_clk; | 477 | goto err_put_clk; |
478 | } | 478 | } |
479 | omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; | 479 | dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG; |
480 | 480 | ||
481 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 481 | res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
482 | if (!res) { | 482 | if (!res) { |
@@ -484,7 +484,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) | |||
484 | ret = -ENODEV; | 484 | ret = -ENODEV; |
485 | goto err_put_clk; | 485 | goto err_put_clk; |
486 | } | 486 | } |
487 | omap_dmic_dai_dma_params.dma_req = res->start; | 487 | |
488 | dmic->dma_req = res->start; | ||
489 | dmic->dma_data.filter_data = &dmic->dma_req; | ||
488 | 490 | ||
489 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); | 491 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); |
490 | if (!res) { | 492 | if (!res) { |
@@ -493,21 +495,12 @@ static int asoc_dmic_probe(struct platform_device *pdev) | |||
493 | goto err_put_clk; | 495 | goto err_put_clk; |
494 | } | 496 | } |
495 | 497 | ||
496 | if (!devm_request_mem_region(&pdev->dev, res->start, | 498 | dmic->io_base = devm_ioremap_resource(&pdev->dev, res); |
497 | resource_size(res), pdev->name)) { | 499 | if (IS_ERR(dmic->io_base)) |
498 | dev_err(dmic->dev, "memory region already claimed\n"); | 500 | return PTR_ERR(dmic->io_base); |
499 | ret = -ENODEV; | ||
500 | goto err_put_clk; | ||
501 | } | ||
502 | |||
503 | dmic->io_base = devm_ioremap(&pdev->dev, res->start, | ||
504 | resource_size(res)); | ||
505 | if (!dmic->io_base) { | ||
506 | ret = -ENOMEM; | ||
507 | goto err_put_clk; | ||
508 | } | ||
509 | 501 | ||
510 | ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); | 502 | ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component, |
503 | &omap_dmic_dai, 1); | ||
511 | if (ret) | 504 | if (ret) |
512 | goto err_put_clk; | 505 | goto err_put_clk; |
513 | 506 | ||
@@ -522,7 +515,7 @@ static int asoc_dmic_remove(struct platform_device *pdev) | |||
522 | { | 515 | { |
523 | struct omap_dmic *dmic = platform_get_drvdata(pdev); | 516 | struct omap_dmic *dmic = platform_get_drvdata(pdev); |
524 | 517 | ||
525 | snd_soc_unregister_dai(&pdev->dev); | 518 | snd_soc_unregister_component(&pdev->dev); |
526 | clk_put(dmic->fclk); | 519 | clk_put(dmic->fclk); |
527 | 520 | ||
528 | return 0; | 521 | return 0; |
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index 32fa840c493e..ced3b88b44d4 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c | |||
@@ -32,15 +32,16 @@ | |||
32 | #include <sound/soc.h> | 32 | #include <sound/soc.h> |
33 | #include <sound/asound.h> | 33 | #include <sound/asound.h> |
34 | #include <sound/asoundef.h> | 34 | #include <sound/asoundef.h> |
35 | #include <sound/dmaengine_pcm.h> | ||
35 | #include <video/omapdss.h> | 36 | #include <video/omapdss.h> |
36 | 37 | ||
37 | #include "omap-pcm.h" | ||
38 | #include "omap-hdmi.h" | 38 | #include "omap-hdmi.h" |
39 | 39 | ||
40 | #define DRV_NAME "omap-hdmi-audio-dai" | 40 | #define DRV_NAME "omap-hdmi-audio-dai" |
41 | 41 | ||
42 | struct hdmi_priv { | 42 | struct hdmi_priv { |
43 | struct omap_pcm_dma_data dma_params; | 43 | struct snd_dmaengine_dai_dma_data dma_data; |
44 | unsigned int dma_req; | ||
44 | struct omap_dss_audio dss_audio; | 45 | struct omap_dss_audio dss_audio; |
45 | struct snd_aes_iec958 iec; | 46 | struct snd_aes_iec958 iec; |
46 | struct snd_cea_861_aud_if cea; | 47 | struct snd_cea_861_aud_if cea; |
@@ -68,7 +69,7 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, | |||
68 | return -ENODEV; | 69 | return -ENODEV; |
69 | } | 70 | } |
70 | 71 | ||
71 | snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params); | 72 | snd_soc_dai_set_dma_data(dai, substream, &priv->dma_data); |
72 | 73 | ||
73 | return 0; | 74 | return 0; |
74 | } | 75 | } |
@@ -88,25 +89,20 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, | |||
88 | struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); | 89 | struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); |
89 | struct snd_aes_iec958 *iec = &priv->iec; | 90 | struct snd_aes_iec958 *iec = &priv->iec; |
90 | struct snd_cea_861_aud_if *cea = &priv->cea; | 91 | struct snd_cea_861_aud_if *cea = &priv->cea; |
91 | struct omap_pcm_dma_data *dma_data; | ||
92 | int err = 0; | 92 | int err = 0; |
93 | 93 | ||
94 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | ||
95 | |||
96 | switch (params_format(params)) { | 94 | switch (params_format(params)) { |
97 | case SNDRV_PCM_FORMAT_S16_LE: | 95 | case SNDRV_PCM_FORMAT_S16_LE: |
98 | dma_data->packet_size = 16; | 96 | priv->dma_data.maxburst = 16; |
99 | break; | 97 | break; |
100 | case SNDRV_PCM_FORMAT_S24_LE: | 98 | case SNDRV_PCM_FORMAT_S24_LE: |
101 | dma_data->packet_size = 32; | 99 | priv->dma_data.maxburst = 32; |
102 | break; | 100 | break; |
103 | default: | 101 | default: |
104 | dev_err(dai->dev, "format not supported!\n"); | 102 | dev_err(dai->dev, "format not supported!\n"); |
105 | return -EINVAL; | 103 | return -EINVAL; |
106 | } | 104 | } |
107 | 105 | ||
108 | dma_data->data_type = 32; | ||
109 | |||
110 | /* | 106 | /* |
111 | * fill the IEC-60958 channel status word | 107 | * fill the IEC-60958 channel status word |
112 | */ | 108 | */ |
@@ -264,6 +260,10 @@ static struct snd_soc_dai_driver omap_hdmi_dai = { | |||
264 | .ops = &omap_hdmi_dai_ops, | 260 | .ops = &omap_hdmi_dai_ops, |
265 | }; | 261 | }; |
266 | 262 | ||
263 | static const struct snd_soc_component_driver omap_hdmi_component = { | ||
264 | .name = DRV_NAME, | ||
265 | }; | ||
266 | |||
267 | static int omap_hdmi_probe(struct platform_device *pdev) | 267 | static int omap_hdmi_probe(struct platform_device *pdev) |
268 | { | 268 | { |
269 | int ret; | 269 | int ret; |
@@ -283,8 +283,7 @@ static int omap_hdmi_probe(struct platform_device *pdev) | |||
283 | return -ENODEV; | 283 | return -ENODEV; |
284 | } | 284 | } |
285 | 285 | ||
286 | hdmi_data->dma_params.port_addr = hdmi_rsrc->start | 286 | hdmi_data->dma_data.addr = hdmi_rsrc->start + OMAP_HDMI_AUDIO_DMA_PORT; |
287 | + OMAP_HDMI_AUDIO_DMA_PORT; | ||
288 | 287 | ||
289 | hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 288 | hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
290 | if (!hdmi_rsrc) { | 289 | if (!hdmi_rsrc) { |
@@ -292,8 +291,9 @@ static int omap_hdmi_probe(struct platform_device *pdev) | |||
292 | return -ENODEV; | 291 | return -ENODEV; |
293 | } | 292 | } |
294 | 293 | ||
295 | hdmi_data->dma_params.dma_req = hdmi_rsrc->start; | 294 | hdmi_data->dma_req = hdmi_rsrc->start; |
296 | hdmi_data->dma_params.name = "HDMI playback"; | 295 | hdmi_data->dma_data.filter_data = &hdmi_data->dma_req; |
296 | hdmi_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
297 | 297 | ||
298 | /* | 298 | /* |
299 | * TODO: We assume that there is only one DSS HDMI device. Future | 299 | * TODO: We assume that there is only one DSS HDMI device. Future |
@@ -321,7 +321,8 @@ static int omap_hdmi_probe(struct platform_device *pdev) | |||
321 | } | 321 | } |
322 | 322 | ||
323 | dev_set_drvdata(&pdev->dev, hdmi_data); | 323 | dev_set_drvdata(&pdev->dev, hdmi_data); |
324 | ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai); | 324 | ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component, |
325 | &omap_hdmi_dai, 1); | ||
325 | 326 | ||
326 | return ret; | 327 | return ret; |
327 | } | 328 | } |
@@ -330,7 +331,7 @@ static int omap_hdmi_remove(struct platform_device *pdev) | |||
330 | { | 331 | { |
331 | struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev); | 332 | struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev); |
332 | 333 | ||
333 | snd_soc_unregister_dai(&pdev->dev); | 334 | snd_soc_unregister_component(&pdev->dev); |
334 | 335 | ||
335 | if (hdmi_data == NULL) { | 336 | if (hdmi_data == NULL) { |
336 | dev_err(&pdev->dev, "cannot obtain HDMi data\n"); | 337 | dev_err(&pdev->dev, "cannot obtain HDMi data\n"); |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8d2defd6fdbe..eadbfb6b5000 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
35 | #include <sound/soc.h> | 35 | #include <sound/soc.h> |
36 | #include <sound/dmaengine_pcm.h> | ||
36 | 37 | ||
37 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 38 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
38 | #include "mcbsp.h" | 39 | #include "mcbsp.h" |
39 | #include "omap-mcbsp.h" | 40 | #include "omap-mcbsp.h" |
40 | #include "omap-pcm.h" | ||
41 | 41 | ||
42 | #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) | 42 | #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) |
43 | 43 | ||
@@ -62,24 +62,22 @@ enum { | |||
62 | * Stream DMA parameters. DMA request line and port address are set runtime | 62 | * Stream DMA parameters. DMA request line and port address are set runtime |
63 | * since they are different between OMAP1 and later OMAPs | 63 | * since they are different between OMAP1 and later OMAPs |
64 | */ | 64 | */ |
65 | static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | 65 | static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream, |
66 | unsigned int packet_size) | ||
66 | { | 67 | { |
67 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 68 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
68 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 69 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
69 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | 70 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
70 | struct omap_pcm_dma_data *dma_data; | ||
71 | int words; | 71 | int words; |
72 | 72 | ||
73 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
74 | |||
75 | /* | 73 | /* |
76 | * Configure McBSP threshold based on either: | 74 | * Configure McBSP threshold based on either: |
77 | * packet_size, when the sDMA is in packet mode, or based on the | 75 | * packet_size, when the sDMA is in packet mode, or based on the |
78 | * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 | 76 | * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 |
79 | * for mono streams. | 77 | * for mono streams. |
80 | */ | 78 | */ |
81 | if (dma_data->packet_size) | 79 | if (packet_size) |
82 | words = dma_data->packet_size; | 80 | words = packet_size; |
83 | else | 81 | else |
84 | words = 1; | 82 | words = 1; |
85 | 83 | ||
@@ -226,7 +224,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
226 | { | 224 | { |
227 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | 225 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
228 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; | 226 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
229 | struct omap_pcm_dma_data *dma_data; | 227 | struct snd_dmaengine_dai_dma_data *dma_data; |
230 | int wlen, channels, wpf; | 228 | int wlen, channels, wpf; |
231 | int pkt_size = 0; | 229 | int pkt_size = 0; |
232 | unsigned int format, div, framesize, master; | 230 | unsigned int format, div, framesize, master; |
@@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
245 | return -EINVAL; | 243 | return -EINVAL; |
246 | } | 244 | } |
247 | if (mcbsp->pdata->buffer_size) { | 245 | if (mcbsp->pdata->buffer_size) { |
248 | dma_data->set_threshold = omap_mcbsp_set_threshold; | ||
249 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { | 246 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { |
250 | int period_words, max_thrsh; | 247 | int period_words, max_thrsh; |
251 | int divider = 0; | 248 | int divider = 0; |
@@ -276,9 +273,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
276 | /* Use packet mode for non mono streams */ | 273 | /* Use packet mode for non mono streams */ |
277 | pkt_size = channels; | 274 | pkt_size = channels; |
278 | } | 275 | } |
276 | omap_mcbsp_set_threshold(substream, pkt_size); | ||
279 | } | 277 | } |
280 | 278 | ||
281 | dma_data->packet_size = pkt_size; | 279 | dma_data->maxburst = pkt_size; |
282 | 280 | ||
283 | if (mcbsp->configured) { | 281 | if (mcbsp->configured) { |
284 | /* McBSP already configured by another stream */ | 282 | /* McBSP already configured by another stream */ |
@@ -586,6 +584,10 @@ static struct snd_soc_dai_driver omap_mcbsp_dai = { | |||
586 | .ops = &mcbsp_dai_ops, | 584 | .ops = &mcbsp_dai_ops, |
587 | }; | 585 | }; |
588 | 586 | ||
587 | static const struct snd_soc_component_driver omap_mcbsp_component = { | ||
588 | .name = "omap-mcbsp", | ||
589 | }; | ||
590 | |||
589 | static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, | 591 | static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, |
590 | struct snd_ctl_elem_info *uinfo) | 592 | struct snd_ctl_elem_info *uinfo) |
591 | { | 593 | { |
@@ -793,7 +795,8 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) | |||
793 | 795 | ||
794 | ret = omap_mcbsp_init(pdev); | 796 | ret = omap_mcbsp_init(pdev); |
795 | if (!ret) | 797 | if (!ret) |
796 | return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); | 798 | return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, |
799 | &omap_mcbsp_dai, 1); | ||
797 | 800 | ||
798 | return ret; | 801 | return ret; |
799 | } | 802 | } |
@@ -802,7 +805,7 @@ static int asoc_mcbsp_remove(struct platform_device *pdev) | |||
802 | { | 805 | { |
803 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); | 806 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); |
804 | 807 | ||
805 | snd_soc_unregister_dai(&pdev->dev); | 808 | snd_soc_unregister_component(&pdev->dev); |
806 | 809 | ||
807 | if (mcbsp->pdata->ops && mcbsp->pdata->ops->free) | 810 | if (mcbsp->pdata->ops && mcbsp->pdata->ops->free) |
808 | mcbsp->pdata->ops->free(mcbsp->id); | 811 | mcbsp->pdata->ops->free(mcbsp->id); |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 5ca11bdac21e..eb05c7ed6d05 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -39,11 +39,14 @@ | |||
39 | #include <sound/pcm.h> | 39 | #include <sound/pcm.h> |
40 | #include <sound/pcm_params.h> | 40 | #include <sound/pcm_params.h> |
41 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | #include <sound/dmaengine_pcm.h> | ||
42 | 43 | ||
43 | #include "omap-mcpdm.h" | 44 | #include "omap-mcpdm.h" |
44 | #include "omap-pcm.h" | ||
45 | 45 | ||
46 | #define OMAP44XX_MCPDM_L3_BASE 0x49032000 | 46 | struct mcpdm_link_config { |
47 | u32 link_mask; /* channel mask for the direction */ | ||
48 | u32 threshold; /* FIFO threshold */ | ||
49 | }; | ||
47 | 50 | ||
48 | struct omap_mcpdm { | 51 | struct omap_mcpdm { |
49 | struct device *dev; | 52 | struct device *dev; |
@@ -53,29 +56,22 @@ struct omap_mcpdm { | |||
53 | 56 | ||
54 | struct mutex mutex; | 57 | struct mutex mutex; |
55 | 58 | ||
56 | /* channel data */ | 59 | /* Playback/Capture configuration */ |
57 | u32 dn_channels; | 60 | struct mcpdm_link_config config[2]; |
58 | u32 up_channels; | ||
59 | |||
60 | /* McPDM FIFO thresholds */ | ||
61 | u32 dn_threshold; | ||
62 | u32 up_threshold; | ||
63 | 61 | ||
64 | /* McPDM dn offsets for rx1, and 2 channels */ | 62 | /* McPDM dn offsets for rx1, and 2 channels */ |
65 | u32 dn_rx_offset; | 63 | u32 dn_rx_offset; |
64 | |||
65 | /* McPDM needs to be restarted due to runtime reconfiguration */ | ||
66 | bool restart; | ||
67 | |||
68 | struct snd_dmaengine_dai_dma_data dma_data[2]; | ||
69 | unsigned int dma_req[2]; | ||
66 | }; | 70 | }; |
67 | 71 | ||
68 | /* | 72 | /* |
69 | * Stream DMA parameters | 73 | * Stream DMA parameters |
70 | */ | 74 | */ |
71 | static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { | ||
72 | { | ||
73 | .name = "Audio playback", | ||
74 | }, | ||
75 | { | ||
76 | .name = "Audio capture", | ||
77 | }, | ||
78 | }; | ||
79 | 75 | ||
80 | static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) | 76 | static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) |
81 | { | 77 | { |
@@ -130,11 +126,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {} | |||
130 | static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) | 126 | static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) |
131 | { | 127 | { |
132 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); | 128 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); |
129 | u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; | ||
133 | 130 | ||
134 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | 131 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); |
135 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | 132 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); |
136 | 133 | ||
137 | ctrl |= mcpdm->dn_channels | mcpdm->up_channels; | 134 | ctrl |= link_mask; |
138 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | 135 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); |
139 | 136 | ||
140 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | 137 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); |
@@ -148,11 +145,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) | |||
148 | static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) | 145 | static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) |
149 | { | 146 | { |
150 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); | 147 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); |
148 | u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK; | ||
151 | 149 | ||
152 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | 150 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); |
153 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | 151 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); |
154 | 152 | ||
155 | ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); | 153 | ctrl &= ~(link_mask); |
156 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | 154 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); |
157 | 155 | ||
158 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | 156 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); |
@@ -188,8 +186,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) | |||
188 | omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); | 186 | omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); |
189 | } | 187 | } |
190 | 188 | ||
191 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); | 189 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, |
192 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); | 190 | mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold); |
191 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, | ||
192 | mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold); | ||
193 | 193 | ||
194 | omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, | 194 | omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, |
195 | MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); | 195 | MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); |
@@ -267,7 +267,7 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, | |||
267 | mutex_unlock(&mcpdm->mutex); | 267 | mutex_unlock(&mcpdm->mutex); |
268 | 268 | ||
269 | snd_soc_dai_set_dma_data(dai, substream, | 269 | snd_soc_dai_set_dma_data(dai, substream, |
270 | &omap_mcpdm_dai_dma_params[substream->stream]); | 270 | &mcpdm->dma_data[substream->stream]); |
271 | 271 | ||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
@@ -283,6 +283,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, | |||
283 | if (omap_mcpdm_active(mcpdm)) { | 283 | if (omap_mcpdm_active(mcpdm)) { |
284 | omap_mcpdm_stop(mcpdm); | 284 | omap_mcpdm_stop(mcpdm); |
285 | omap_mcpdm_close_streams(mcpdm); | 285 | omap_mcpdm_close_streams(mcpdm); |
286 | mcpdm->config[0].link_mask = 0; | ||
287 | mcpdm->config[1].link_mask = 0; | ||
286 | } | 288 | } |
287 | } | 289 | } |
288 | 290 | ||
@@ -295,7 +297,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
295 | { | 297 | { |
296 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); | 298 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
297 | int stream = substream->stream; | 299 | int stream = substream->stream; |
298 | struct omap_pcm_dma_data *dma_data; | 300 | struct snd_dmaengine_dai_dma_data *dma_data; |
301 | u32 threshold; | ||
299 | int channels; | 302 | int channels; |
300 | int link_mask = 0; | 303 | int link_mask = 0; |
301 | 304 | ||
@@ -325,16 +328,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
325 | 328 | ||
326 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | 329 | dma_data = snd_soc_dai_get_dma_data(dai, substream); |
327 | 330 | ||
331 | threshold = mcpdm->config[stream].threshold; | ||
328 | /* Configure McPDM channels, and DMA packet size */ | 332 | /* Configure McPDM channels, and DMA packet size */ |
329 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 333 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
330 | mcpdm->dn_channels = link_mask << 3; | 334 | link_mask <<= 3; |
331 | dma_data->packet_size = | 335 | |
332 | (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; | 336 | /* If capture is not running assume a stereo stream to come */ |
337 | if (!mcpdm->config[!stream].link_mask) | ||
338 | mcpdm->config[!stream].link_mask = 0x3; | ||
339 | |||
340 | dma_data->maxburst = | ||
341 | (MCPDM_DN_THRES_MAX - threshold) * channels; | ||
333 | } else { | 342 | } else { |
334 | mcpdm->up_channels = link_mask << 0; | 343 | /* If playback is not running assume a stereo stream to come */ |
335 | dma_data->packet_size = mcpdm->up_threshold * channels; | 344 | if (!mcpdm->config[!stream].link_mask) |
345 | mcpdm->config[!stream].link_mask = (0x3 << 3); | ||
346 | |||
347 | dma_data->maxburst = threshold * channels; | ||
336 | } | 348 | } |
337 | 349 | ||
350 | /* Check if we need to restart McPDM with this stream */ | ||
351 | if (mcpdm->config[stream].link_mask && | ||
352 | mcpdm->config[stream].link_mask != link_mask) | ||
353 | mcpdm->restart = true; | ||
354 | |||
355 | mcpdm->config[stream].link_mask = link_mask; | ||
356 | |||
338 | return 0; | 357 | return 0; |
339 | } | 358 | } |
340 | 359 | ||
@@ -346,6 +365,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, | |||
346 | if (!omap_mcpdm_active(mcpdm)) { | 365 | if (!omap_mcpdm_active(mcpdm)) { |
347 | omap_mcpdm_start(mcpdm); | 366 | omap_mcpdm_start(mcpdm); |
348 | omap_mcpdm_reg_dump(mcpdm); | 367 | omap_mcpdm_reg_dump(mcpdm); |
368 | } else if (mcpdm->restart) { | ||
369 | omap_mcpdm_stop(mcpdm); | ||
370 | omap_mcpdm_start(mcpdm); | ||
371 | mcpdm->restart = false; | ||
372 | omap_mcpdm_reg_dump(mcpdm); | ||
349 | } | 373 | } |
350 | 374 | ||
351 | return 0; | 375 | return 0; |
@@ -369,7 +393,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) | |||
369 | pm_runtime_get_sync(mcpdm->dev); | 393 | pm_runtime_get_sync(mcpdm->dev); |
370 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); | 394 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); |
371 | 395 | ||
372 | ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, | 396 | ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler, |
373 | 0, "McPDM", (void *)mcpdm); | 397 | 0, "McPDM", (void *)mcpdm); |
374 | 398 | ||
375 | pm_runtime_put_sync(mcpdm->dev); | 399 | pm_runtime_put_sync(mcpdm->dev); |
@@ -380,8 +404,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) | |||
380 | } | 404 | } |
381 | 405 | ||
382 | /* Configure McPDM threshold values */ | 406 | /* Configure McPDM threshold values */ |
383 | mcpdm->dn_threshold = 2; | 407 | mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; |
384 | mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; | 408 | mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = |
409 | MCPDM_UP_THRES_MAX - 3; | ||
385 | return ret; | 410 | return ret; |
386 | } | 411 | } |
387 | 412 | ||
@@ -389,7 +414,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) | |||
389 | { | 414 | { |
390 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); | 415 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
391 | 416 | ||
392 | free_irq(mcpdm->irq, (void *)mcpdm); | ||
393 | pm_runtime_disable(mcpdm->dev); | 417 | pm_runtime_disable(mcpdm->dev); |
394 | 418 | ||
395 | return 0; | 419 | return 0; |
@@ -420,6 +444,10 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { | |||
420 | .ops = &omap_mcpdm_dai_ops, | 444 | .ops = &omap_mcpdm_dai_ops, |
421 | }; | 445 | }; |
422 | 446 | ||
447 | static const struct snd_soc_component_driver omap_mcpdm_component = { | ||
448 | .name = "omap-mcpdm", | ||
449 | }; | ||
450 | |||
423 | void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, | 451 | void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, |
424 | u8 rx1, u8 rx2) | 452 | u8 rx1, u8 rx2) |
425 | { | 453 | { |
@@ -446,33 +474,30 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) | |||
446 | if (res == NULL) | 474 | if (res == NULL) |
447 | return -ENOMEM; | 475 | return -ENOMEM; |
448 | 476 | ||
449 | omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA; | 477 | mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA; |
450 | omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA; | 478 | mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA; |
451 | 479 | ||
452 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); | 480 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); |
453 | if (!res) | 481 | if (!res) |
454 | return -ENODEV; | 482 | return -ENODEV; |
455 | 483 | ||
456 | omap_mcpdm_dai_dma_params[0].dma_req = res->start; | 484 | mcpdm->dma_req[0] = res->start; |
485 | mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0]; | ||
457 | 486 | ||
458 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); | 487 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); |
459 | if (!res) | 488 | if (!res) |
460 | return -ENODEV; | 489 | return -ENODEV; |
461 | 490 | ||
462 | omap_mcpdm_dai_dma_params[1].dma_req = res->start; | 491 | mcpdm->dma_req[1] = res->start; |
492 | mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1]; | ||
463 | 493 | ||
464 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); | 494 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); |
465 | if (res == NULL) | 495 | if (res == NULL) |
466 | return -ENOMEM; | 496 | return -ENOMEM; |
467 | 497 | ||
468 | if (!devm_request_mem_region(&pdev->dev, res->start, | 498 | mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res); |
469 | resource_size(res), "McPDM")) | 499 | if (IS_ERR(mcpdm->io_base)) |
470 | return -EBUSY; | 500 | return PTR_ERR(mcpdm->io_base); |
471 | |||
472 | mcpdm->io_base = devm_ioremap(&pdev->dev, res->start, | ||
473 | resource_size(res)); | ||
474 | if (!mcpdm->io_base) | ||
475 | return -ENOMEM; | ||
476 | 501 | ||
477 | mcpdm->irq = platform_get_irq(pdev, 0); | 502 | mcpdm->irq = platform_get_irq(pdev, 0); |
478 | if (mcpdm->irq < 0) | 503 | if (mcpdm->irq < 0) |
@@ -480,12 +505,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) | |||
480 | 505 | ||
481 | mcpdm->dev = &pdev->dev; | 506 | mcpdm->dev = &pdev->dev; |
482 | 507 | ||
483 | return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); | 508 | return snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, |
509 | &omap_mcpdm_dai, 1); | ||
484 | } | 510 | } |
485 | 511 | ||
486 | static int asoc_mcpdm_remove(struct platform_device *pdev) | 512 | static int asoc_mcpdm_remove(struct platform_device *pdev) |
487 | { | 513 | { |
488 | snd_soc_unregister_dai(&pdev->dev); | 514 | snd_soc_unregister_component(&pdev->dev); |
489 | return 0; | 515 | return 0; |
490 | } | 516 | } |
491 | 517 | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index c722c2ef9665..c28e042f2208 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <sound/dmaengine_pcm.h> | 32 | #include <sound/dmaengine_pcm.h> |
33 | #include <sound/soc.h> | 33 | #include <sound/soc.h> |
34 | 34 | ||
35 | #include "omap-pcm.h" | ||
36 | |||
37 | #ifdef CONFIG_ARCH_OMAP1 | 35 | #ifdef CONFIG_ARCH_OMAP1 |
38 | #define pcm_omap1510() cpu_is_omap1510() | 36 | #define pcm_omap1510() cpu_is_omap1510() |
39 | #else | 37 | #else |
@@ -56,25 +54,6 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { | |||
56 | .buffer_bytes_max = 128 * 1024, | 54 | .buffer_bytes_max = 128 * 1024, |
57 | }; | 55 | }; |
58 | 56 | ||
59 | static int omap_pcm_get_dma_buswidth(int num_bits) | ||
60 | { | ||
61 | int buswidth; | ||
62 | |||
63 | switch (num_bits) { | ||
64 | case 16: | ||
65 | buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
66 | break; | ||
67 | case 32: | ||
68 | buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
69 | break; | ||
70 | default: | ||
71 | buswidth = -EINVAL; | ||
72 | break; | ||
73 | } | ||
74 | return buswidth; | ||
75 | } | ||
76 | |||
77 | |||
78 | /* this may get called several times by oss emulation */ | 57 | /* this may get called several times by oss emulation */ |
79 | static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | 58 | static int omap_pcm_hw_params(struct snd_pcm_substream *substream, |
80 | struct snd_pcm_hw_params *params) | 59 | struct snd_pcm_hw_params *params) |
@@ -105,20 +84,9 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | |||
105 | if (err) | 84 | if (err) |
106 | return err; | 85 | return err; |
107 | 86 | ||
108 | /* Override the *_dma addr_width if requested by the DAI driver */ | 87 | snd_dmaengine_pcm_set_config_from_dai_data(substream, |
109 | if (dma_data->data_type) { | 88 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream), |
110 | int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type); | 89 | &config); |
111 | |||
112 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
113 | config.dst_addr_width = buswidth; | ||
114 | else | ||
115 | config.src_addr_width = buswidth; | ||
116 | } | ||
117 | |||
118 | config.src_addr = dma_data->port_addr; | ||
119 | config.dst_addr = dma_data->port_addr; | ||
120 | config.src_maxburst = dma_data->packet_size; | ||
121 | config.dst_maxburst = dma_data->packet_size; | ||
122 | 90 | ||
123 | return dmaengine_slave_config(chan, &config); | 91 | return dmaengine_slave_config(chan, &config); |
124 | } | 92 | } |
@@ -129,37 +97,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream) | |||
129 | return 0; | 97 | return 0; |
130 | } | 98 | } |
131 | 99 | ||
132 | static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
133 | { | ||
134 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
135 | struct omap_pcm_dma_data *dma_data; | ||
136 | int ret = 0; | ||
137 | |||
138 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
139 | |||
140 | switch (cmd) { | ||
141 | case SNDRV_PCM_TRIGGER_START: | ||
142 | case SNDRV_PCM_TRIGGER_RESUME: | ||
143 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
144 | /* Configure McBSP internal buffer usage */ | ||
145 | if (dma_data->set_threshold) | ||
146 | dma_data->set_threshold(substream); | ||
147 | break; | ||
148 | |||
149 | case SNDRV_PCM_TRIGGER_STOP: | ||
150 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
151 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
152 | break; | ||
153 | default: | ||
154 | ret = -EINVAL; | ||
155 | } | ||
156 | |||
157 | if (ret == 0) | ||
158 | ret = snd_dmaengine_pcm_trigger(substream, cmd); | ||
159 | |||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | 100 | static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) |
164 | { | 101 | { |
165 | snd_pcm_uframes_t offset; | 102 | snd_pcm_uframes_t offset; |
@@ -175,20 +112,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | |||
175 | static int omap_pcm_open(struct snd_pcm_substream *substream) | 112 | static int omap_pcm_open(struct snd_pcm_substream *substream) |
176 | { | 113 | { |
177 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 114 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
178 | struct omap_pcm_dma_data *dma_data; | 115 | struct snd_dmaengine_dai_dma_data *dma_data; |
179 | 116 | ||
180 | snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); | 117 | snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); |
181 | 118 | ||
182 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 119 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
183 | 120 | ||
184 | return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, | 121 | return snd_dmaengine_pcm_open_request_chan(substream, |
185 | &dma_data->dma_req); | 122 | omap_dma_filter_fn, |
186 | } | 123 | dma_data->filter_data); |
187 | |||
188 | static int omap_pcm_close(struct snd_pcm_substream *substream) | ||
189 | { | ||
190 | snd_dmaengine_pcm_close(substream); | ||
191 | return 0; | ||
192 | } | 124 | } |
193 | 125 | ||
194 | static int omap_pcm_mmap(struct snd_pcm_substream *substream, | 126 | static int omap_pcm_mmap(struct snd_pcm_substream *substream, |
@@ -204,11 +136,11 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, | |||
204 | 136 | ||
205 | static struct snd_pcm_ops omap_pcm_ops = { | 137 | static struct snd_pcm_ops omap_pcm_ops = { |
206 | .open = omap_pcm_open, | 138 | .open = omap_pcm_open, |
207 | .close = omap_pcm_close, | 139 | .close = snd_dmaengine_pcm_close_release_chan, |
208 | .ioctl = snd_pcm_lib_ioctl, | 140 | .ioctl = snd_pcm_lib_ioctl, |
209 | .hw_params = omap_pcm_hw_params, | 141 | .hw_params = omap_pcm_hw_params, |
210 | .hw_free = omap_pcm_hw_free, | 142 | .hw_free = omap_pcm_hw_free, |
211 | .trigger = omap_pcm_trigger, | 143 | .trigger = snd_dmaengine_pcm_trigger, |
212 | .pointer = omap_pcm_pointer, | 144 | .pointer = omap_pcm_pointer, |
213 | .mmap = omap_pcm_mmap, | 145 | .mmap = omap_pcm_mmap, |
214 | }; | 146 | }; |
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h deleted file mode 100644 index cabe74c4068b..000000000000 --- a/sound/soc/omap/omap-pcm.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * omap-pcm.h | ||
3 | * | ||
4 | * Copyright (C) 2008 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> | ||
7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
21 | * 02110-1301 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef __OMAP_PCM_H__ | ||
26 | #define __OMAP_PCM_H__ | ||
27 | |||
28 | struct snd_pcm_substream; | ||
29 | |||
30 | struct omap_pcm_dma_data { | ||
31 | char *name; /* stream identifier */ | ||
32 | int dma_req; /* DMA request line */ | ||
33 | unsigned long port_addr; /* transmit/receive register */ | ||
34 | void (*set_threshold)(struct snd_pcm_substream *substream); | ||
35 | int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm | ||
36 | * to decide the sDMA data type */ | ||
37 | int packet_size; /* packet size only in PACKET mode */ | ||
38 | }; | ||
39 | |||
40 | #endif | ||
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index fd98509d0f49..2a9324f794d8 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <sound/jack.h> | 43 | #include <sound/jack.h> |
44 | 44 | ||
45 | #include "omap-mcbsp.h" | 45 | #include "omap-mcbsp.h" |
46 | #include "omap-pcm.h" | ||
47 | 46 | ||
48 | struct omap_twl4030 { | 47 | struct omap_twl4030 { |
49 | int jack_detect; /* board can detect jack events */ | 48 | int jack_detect; /* board can detect jack events */ |
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 805512f2555a..cf604a2faa18 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 34 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
35 | 35 | ||
36 | #include "omap-mcbsp.h" | 36 | #include "omap-mcbsp.h" |
37 | #include "omap-pcm.h" | ||
38 | 37 | ||
39 | #define OMAP3_PANDORA_DAC_POWER_GPIO 118 | 38 | #define OMAP3_PANDORA_DAC_POWER_GPIO 118 |
40 | #define OMAP3_PANDORA_AMP_POWER_GPIO 14 | 39 | #define OMAP3_PANDORA_AMP_POWER_GPIO 14 |
@@ -80,12 +79,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream, | |||
80 | static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, | 79 | static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, |
81 | struct snd_kcontrol *k, int event) | 80 | struct snd_kcontrol *k, int event) |
82 | { | 81 | { |
82 | int ret; | ||
83 | |||
83 | /* | 84 | /* |
84 | * The PCM1773 DAC datasheet requires 1ms delay between switching | 85 | * The PCM1773 DAC datasheet requires 1ms delay between switching |
85 | * VCC power on/off and /PD pin high/low | 86 | * VCC power on/off and /PD pin high/low |
86 | */ | 87 | */ |
87 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 88 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
88 | regulator_enable(omap3pandora_dac_reg); | 89 | ret = regulator_enable(omap3pandora_dac_reg); |
90 | if (ret) { | ||
91 | dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret); | ||
92 | return ret; | ||
93 | } | ||
89 | mdelay(1); | 94 | mdelay(1); |
90 | gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); | 95 | gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); |
91 | } else { | 96 | } else { |
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index 06ef8d67ed1c..d03e57da7708 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 33 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
34 | 34 | ||
35 | #include "omap-mcbsp.h" | 35 | #include "omap-mcbsp.h" |
36 | #include "omap-pcm.h" | ||
37 | #include "../codecs/tlv320aic23.h" | 36 | #include "../codecs/tlv320aic23.h" |
38 | 37 | ||
39 | #define CODEC_CLOCK 12000000 | 38 | #define CODEC_CLOCK 12000000 |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 3cd525748975..249cd230ad8f 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
38 | 38 | ||
39 | #include "omap-mcbsp.h" | 39 | #include "omap-mcbsp.h" |
40 | #include "omap-pcm.h" | ||
41 | 40 | ||
42 | #define RX51_TVOUT_SEL_GPIO 40 | 41 | #define RX51_TVOUT_SEL_GPIO 40 |
43 | #define RX51_JACK_DETECT_GPIO 177 | 42 | #define RX51_JACK_DETECT_GPIO 177 |
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 190eb0bccf5f..349930015264 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c | |||
@@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) | |||
118 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 118 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
119 | struct platform_device *pdev = to_platform_device(rtd->platform->dev); | 119 | struct platform_device *pdev = to_platform_device(rtd->platform->dev); |
120 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 120 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
121 | struct mmp_dma_data *dma_data; | 121 | struct mmp_dma_data dma_data; |
122 | struct resource *r; | 122 | struct resource *r; |
123 | int ret; | ||
124 | 123 | ||
125 | r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); | 124 | r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); |
126 | if (!r) | 125 | if (!r) |
@@ -128,33 +127,12 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) | |||
128 | 127 | ||
129 | snd_soc_set_runtime_hwparams(substream, | 128 | snd_soc_set_runtime_hwparams(substream, |
130 | &mmp_pcm_hardware[substream->stream]); | 129 | &mmp_pcm_hardware[substream->stream]); |
131 | dma_data = devm_kzalloc(&pdev->dev, | ||
132 | sizeof(struct mmp_dma_data), GFP_KERNEL); | ||
133 | if (dma_data == NULL) | ||
134 | return -ENOMEM; | ||
135 | 130 | ||
136 | dma_data->dma_res = r; | 131 | dma_data.dma_res = r; |
137 | dma_data->ssp_id = cpu_dai->id; | 132 | dma_data.ssp_id = cpu_dai->id; |
138 | 133 | ||
139 | ret = snd_dmaengine_pcm_open(substream, filter, dma_data); | 134 | return snd_dmaengine_pcm_open_request_chan(substream, filter, |
140 | if (ret) { | 135 | &dma_data); |
141 | devm_kfree(&pdev->dev, dma_data); | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | snd_dmaengine_pcm_set_data(substream, dma_data); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int mmp_pcm_close(struct snd_pcm_substream *substream) | ||
150 | { | ||
151 | struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); | ||
152 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
153 | struct platform_device *pdev = to_platform_device(rtd->platform->dev); | ||
154 | |||
155 | snd_dmaengine_pcm_close(substream); | ||
156 | devm_kfree(&pdev->dev, dma_data); | ||
157 | return 0; | ||
158 | } | 136 | } |
159 | 137 | ||
160 | static int mmp_pcm_mmap(struct snd_pcm_substream *substream, | 138 | static int mmp_pcm_mmap(struct snd_pcm_substream *substream, |
@@ -171,7 +149,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, | |||
171 | 149 | ||
172 | struct snd_pcm_ops mmp_pcm_ops = { | 150 | struct snd_pcm_ops mmp_pcm_ops = { |
173 | .open = mmp_pcm_open, | 151 | .open = mmp_pcm_open, |
174 | .close = mmp_pcm_close, | 152 | .close = snd_dmaengine_pcm_close_release_chan, |
175 | .ioctl = snd_pcm_lib_ioctl, | 153 | .ioctl = snd_pcm_lib_ioctl, |
176 | .hw_params = mmp_pcm_hw_params, | 154 | .hw_params = mmp_pcm_hw_params, |
177 | .trigger = snd_dmaengine_pcm_trigger, | 155 | .trigger = snd_dmaengine_pcm_trigger, |
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 9140c4abafbc..a64779980177 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c | |||
@@ -405,6 +405,10 @@ struct snd_soc_dai_driver mmp_sspa_dai = { | |||
405 | .ops = &mmp_sspa_dai_ops, | 405 | .ops = &mmp_sspa_dai_ops, |
406 | }; | 406 | }; |
407 | 407 | ||
408 | static const struct snd_soc_component_driver mmp_sspa_component = { | ||
409 | .name = "mmp-sspa", | ||
410 | }; | ||
411 | |||
408 | static int asoc_mmp_sspa_probe(struct platform_device *pdev) | 412 | static int asoc_mmp_sspa_probe(struct platform_device *pdev) |
409 | { | 413 | { |
410 | struct sspa_priv *priv; | 414 | struct sspa_priv *priv; |
@@ -450,7 +454,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev) | |||
450 | priv->dai_fmt = (unsigned int) -1; | 454 | priv->dai_fmt = (unsigned int) -1; |
451 | platform_set_drvdata(pdev, priv); | 455 | platform_set_drvdata(pdev, priv); |
452 | 456 | ||
453 | return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai); | 457 | return snd_soc_register_component(&pdev->dev, &mmp_sspa_component, |
458 | &mmp_sspa_dai, 1); | ||
454 | } | 459 | } |
455 | 460 | ||
456 | static int asoc_mmp_sspa_remove(struct platform_device *pdev) | 461 | static int asoc_mmp_sspa_remove(struct platform_device *pdev) |
@@ -460,7 +465,7 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev) | |||
460 | clk_disable(priv->audio_clk); | 465 | clk_disable(priv->audio_clk); |
461 | clk_put(priv->audio_clk); | 466 | clk_put(priv->audio_clk); |
462 | clk_put(priv->sysclk); | 467 | clk_put(priv->sysclk); |
463 | snd_soc_unregister_dai(&pdev->dev); | 468 | snd_soc_unregister_component(&pdev->dev); |
464 | return 0; | 469 | return 0; |
465 | } | 470 | } |
466 | 471 | ||
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index d3eb0c2eec77..6f4dd7543e82 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -794,14 +794,19 @@ static struct snd_soc_dai_driver pxa_ssp_dai = { | |||
794 | .ops = &pxa_ssp_dai_ops, | 794 | .ops = &pxa_ssp_dai_ops, |
795 | }; | 795 | }; |
796 | 796 | ||
797 | static const struct snd_soc_component_driver pxa_ssp_component = { | ||
798 | .name = "pxa-ssp", | ||
799 | }; | ||
800 | |||
797 | static int asoc_ssp_probe(struct platform_device *pdev) | 801 | static int asoc_ssp_probe(struct platform_device *pdev) |
798 | { | 802 | { |
799 | return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai); | 803 | return snd_soc_register_component(&pdev->dev, &pxa_ssp_component, |
804 | &pxa_ssp_dai, 1); | ||
800 | } | 805 | } |
801 | 806 | ||
802 | static int asoc_ssp_remove(struct platform_device *pdev) | 807 | static int asoc_ssp_remove(struct platform_device *pdev) |
803 | { | 808 | { |
804 | snd_soc_unregister_dai(&pdev->dev); | 809 | snd_soc_unregister_component(&pdev->dev); |
805 | return 0; | 810 | return 0; |
806 | } | 811 | } |
807 | 812 | ||
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 4b0a009bd683..57ea8e6c5488 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c | |||
@@ -47,6 +47,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = { | |||
47 | .warm_reset = pxa2xx_ac97_warm_reset, | 47 | .warm_reset = pxa2xx_ac97_warm_reset, |
48 | .reset = pxa2xx_ac97_cold_reset, | 48 | .reset = pxa2xx_ac97_cold_reset, |
49 | }; | 49 | }; |
50 | EXPORT_SYMBOL_GPL(soc_ac97_ops); | ||
50 | 51 | ||
51 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { | 52 | static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { |
52 | .name = "AC97 PCM Stereo out", | 53 | .name = "AC97 PCM Stereo out", |
@@ -232,7 +233,9 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { | |||
232 | }, | 233 | }, |
233 | }; | 234 | }; |
234 | 235 | ||
235 | EXPORT_SYMBOL_GPL(soc_ac97_ops); | 236 | static const struct snd_soc_component_driver pxa_ac97_component = { |
237 | .name = "pxa-ac97", | ||
238 | }; | ||
236 | 239 | ||
237 | static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) | 240 | static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) |
238 | { | 241 | { |
@@ -245,13 +248,13 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) | |||
245 | * driver to do interesting things with the clocking to get us up | 248 | * driver to do interesting things with the clocking to get us up |
246 | * and running. | 249 | * and running. |
247 | */ | 250 | */ |
248 | return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver, | 251 | return snd_soc_register_component(&pdev->dev, &pxa_ac97_component, |
249 | ARRAY_SIZE(pxa_ac97_dai_driver)); | 252 | pxa_ac97_dai_driver, ARRAY_SIZE(pxa_ac97_dai_driver)); |
250 | } | 253 | } |
251 | 254 | ||
252 | static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) | 255 | static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) |
253 | { | 256 | { |
254 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver)); | 257 | snd_soc_unregister_component(&pdev->dev); |
255 | return 0; | 258 | return 0; |
256 | } | 259 | } |
257 | 260 | ||
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 6b1a06f67564..f7ca71664112 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c | |||
@@ -360,14 +360,19 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { | |||
360 | .symmetric_rates = 1, | 360 | .symmetric_rates = 1, |
361 | }; | 361 | }; |
362 | 362 | ||
363 | static const struct snd_soc_component_driver pxa_i2s_component = { | ||
364 | .name = "pxa-i2s", | ||
365 | }; | ||
366 | |||
363 | static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) | 367 | static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) |
364 | { | 368 | { |
365 | return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai); | 369 | return snd_soc_register_component(&pdev->dev, &pxa_i2s_component, |
370 | &pxa_i2s_dai, 1); | ||
366 | } | 371 | } |
367 | 372 | ||
368 | static int pxa2xx_i2s_drv_remove(struct platform_device *pdev) | 373 | static int pxa2xx_i2s_drv_remove(struct platform_device *pdev) |
369 | { | 374 | { |
370 | snd_soc_unregister_dai(&pdev->dev); | 375 | snd_soc_unregister_component(&pdev->dev); |
371 | return 0; | 376 | return 0; |
372 | } | 377 | } |
373 | 378 | ||
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index fee4d477a49c..73bb99f0109a 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c | |||
@@ -436,6 +436,10 @@ static struct snd_soc_dai_driver s6000_i2s_dai = { | |||
436 | .ops = &s6000_i2s_dai_ops, | 436 | .ops = &s6000_i2s_dai_ops, |
437 | }; | 437 | }; |
438 | 438 | ||
439 | static const struct snd_soc_component_driver s6000_i2s_component = { | ||
440 | .name = "s6000-i2s", | ||
441 | }; | ||
442 | |||
439 | static int s6000_i2s_probe(struct platform_device *pdev) | 443 | static int s6000_i2s_probe(struct platform_device *pdev) |
440 | { | 444 | { |
441 | struct s6000_i2s_dev *dev; | 445 | struct s6000_i2s_dev *dev; |
@@ -543,7 +547,8 @@ static int s6000_i2s_probe(struct platform_device *pdev) | |||
543 | S6_I2S_INT_UNDERRUN | | 547 | S6_I2S_INT_UNDERRUN | |
544 | S6_I2S_INT_OVERRUN); | 548 | S6_I2S_INT_OVERRUN); |
545 | 549 | ||
546 | ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai); | 550 | ret = snd_soc_register_component(&pdev->dev, &s6000_i2s_component, |
551 | &s6000_i2s_dai, 1); | ||
547 | if (ret) | 552 | if (ret) |
548 | goto err_release_dev; | 553 | goto err_release_dev; |
549 | 554 | ||
@@ -572,7 +577,7 @@ static void s6000_i2s_remove(struct platform_device *pdev) | |||
572 | struct resource *region; | 577 | struct resource *region; |
573 | void __iomem *mmio = dev->scbbase; | 578 | void __iomem *mmio = dev->scbbase; |
574 | 579 | ||
575 | snd_soc_unregister_dai(&pdev->dev); | 580 | snd_soc_unregister_component(&pdev->dev); |
576 | 581 | ||
577 | s6000_i2s_stop_channel(dev, 0); | 582 | s6000_i2s_stop_channel(dev, 0); |
578 | s6000_i2s_stop_channel(dev, 1); | 583 | s6000_i2s_stop_channel(dev, 1); |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 90e7e6653233..475fb0d8b3c6 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -35,11 +35,10 @@ config SND_SAMSUNG_I2S | |||
35 | tristate | 35 | tristate |
36 | 36 | ||
37 | config SND_SOC_SAMSUNG_NEO1973_WM8753 | 37 | config SND_SOC_SAMSUNG_NEO1973_WM8753 |
38 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)" | 38 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" |
39 | depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02) | 39 | depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 |
40 | select SND_S3C24XX_I2S | 40 | select SND_S3C24XX_I2S |
41 | select SND_SOC_WM8753 | 41 | select SND_SOC_WM8753 |
42 | select SND_SOC_LM4857 if MACH_NEO1973_GTA01 | ||
43 | select SND_SOC_DFBMCS320 | 42 | select SND_SOC_DFBMCS320 |
44 | help | 43 | help |
45 | Say Y here to enable audio support for the Openmoko Neo1973 | 44 | Say Y here to enable audio support for the Openmoko Neo1973 |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 0df3c5644cfa..cb88ead98917 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
21 | 21 | ||
22 | #include <mach/dma.h> | 22 | #include <mach/dma.h> |
23 | #include <plat/regs-ac97.h> | 23 | #include "regs-ac97.h" |
24 | #include <linux/platform_data/asoc-s3c.h> | 24 | #include <linux/platform_data/asoc-s3c.h> |
25 | 25 | ||
26 | #include "dma.h" | 26 | #include "dma.h" |
@@ -370,6 +370,10 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { | |||
370 | }, | 370 | }, |
371 | }; | 371 | }; |
372 | 372 | ||
373 | static const struct snd_soc_component_driver s3c_ac97_component = { | ||
374 | .name = "s3c-ac97", | ||
375 | }; | ||
376 | |||
373 | static int s3c_ac97_probe(struct platform_device *pdev) | 377 | static int s3c_ac97_probe(struct platform_device *pdev) |
374 | { | 378 | { |
375 | struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; | 379 | struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; |
@@ -457,8 +461,8 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
457 | goto err4; | 461 | goto err4; |
458 | } | 462 | } |
459 | 463 | ||
460 | ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, | 464 | ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, |
461 | ARRAY_SIZE(s3c_ac97_dai)); | 465 | s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); |
462 | if (ret) | 466 | if (ret) |
463 | goto err5; | 467 | goto err5; |
464 | 468 | ||
@@ -470,7 +474,7 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
470 | 474 | ||
471 | return 0; | 475 | return 0; |
472 | err6: | 476 | err6: |
473 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); | 477 | snd_soc_unregister_component(&pdev->dev); |
474 | err5: | 478 | err5: |
475 | free_irq(irq_res->start, NULL); | 479 | free_irq(irq_res->start, NULL); |
476 | err4: | 480 | err4: |
@@ -490,7 +494,7 @@ static int s3c_ac97_remove(struct platform_device *pdev) | |||
490 | struct resource *mem_res, *irq_res; | 494 | struct resource *mem_res, *irq_res; |
491 | 495 | ||
492 | asoc_dma_platform_unregister(&pdev->dev); | 496 | asoc_dma_platform_unregister(&pdev->dev); |
493 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); | 497 | snd_soc_unregister_component(&pdev->dev); |
494 | 498 | ||
495 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 499 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
496 | if (irq_res) | 500 | if (irq_res) |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index d37ede58e0a8..415ad81999c4 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c | |||
@@ -218,6 +218,10 @@ static struct snd_soc_dai_driver voice_dai = { | |||
218 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 218 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct snd_soc_component_driver voice_component = { | ||
222 | .name = "goni-voice", | ||
223 | }; | ||
224 | |||
221 | static struct snd_soc_ops goni_voice_ops = { | 225 | static struct snd_soc_ops goni_voice_ops = { |
222 | .hw_params = goni_voice_hw_params, | 226 | .hw_params = goni_voice_hw_params, |
223 | }; | 227 | }; |
@@ -270,7 +274,8 @@ static int __init goni_init(void) | |||
270 | return -ENOMEM; | 274 | return -ENOMEM; |
271 | 275 | ||
272 | /* register voice DAI here */ | 276 | /* register voice DAI here */ |
273 | ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); | 277 | ret = snd_soc_register_component(&goni_snd_device->dev, &voice_component, |
278 | &voice_dai, 1); | ||
274 | if (ret) { | 279 | if (ret) { |
275 | platform_device_put(goni_snd_device); | 280 | platform_device_put(goni_snd_device); |
276 | return ret; | 281 | return ret; |
@@ -280,7 +285,7 @@ static int __init goni_init(void) | |||
280 | ret = platform_device_add(goni_snd_device); | 285 | ret = platform_device_add(goni_snd_device); |
281 | 286 | ||
282 | if (ret) { | 287 | if (ret) { |
283 | snd_soc_unregister_dai(&goni_snd_device->dev); | 288 | snd_soc_unregister_component(&goni_snd_device->dev); |
284 | platform_device_put(goni_snd_device); | 289 | platform_device_put(goni_snd_device); |
285 | } | 290 | } |
286 | 291 | ||
@@ -289,7 +294,7 @@ static int __init goni_init(void) | |||
289 | 294 | ||
290 | static void __exit goni_exit(void) | 295 | static void __exit goni_exit(void) |
291 | { | 296 | { |
292 | snd_soc_unregister_dai(&goni_snd_device->dev); | 297 | snd_soc_unregister_component(&goni_snd_device->dev); |
293 | platform_device_unregister(goni_snd_device); | 298 | platform_device_unregister(goni_snd_device); |
294 | } | 299 | } |
295 | 300 | ||
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 15a3817aa5c8..fa91376e323d 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
21 | #include <sound/jack.h> | 21 | #include <sound/jack.h> |
22 | 22 | ||
23 | #include <plat/regs-iis.h> | 23 | #include "regs-iis.h" |
24 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
25 | 25 | ||
26 | #include "s3c24xx-i2s.h" | 26 | #include "s3c24xx-i2s.h" |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 6bbeb0bf1a73..82ebb1a51479 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -963,6 +963,10 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { | |||
963 | .delay = i2s_delay, | 963 | .delay = i2s_delay, |
964 | }; | 964 | }; |
965 | 965 | ||
966 | static const struct snd_soc_component_driver samsung_i2s_component = { | ||
967 | .name = "samsung-i2s", | ||
968 | }; | ||
969 | |||
966 | #define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 | 970 | #define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 |
967 | 971 | ||
968 | #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | 972 | #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ |
@@ -1114,8 +1118,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1114 | dev_err(&pdev->dev, "Unable to get drvdata\n"); | 1118 | dev_err(&pdev->dev, "Unable to get drvdata\n"); |
1115 | return -EFAULT; | 1119 | return -EFAULT; |
1116 | } | 1120 | } |
1117 | snd_soc_register_dai(&sec_dai->pdev->dev, | 1121 | snd_soc_register_component(&sec_dai->pdev->dev, |
1118 | &sec_dai->i2s_dai_drv); | 1122 | &samsung_i2s_component, |
1123 | &sec_dai->i2s_dai_drv, 1); | ||
1119 | asoc_dma_platform_register(&pdev->dev); | 1124 | asoc_dma_platform_register(&pdev->dev); |
1120 | return 0; | 1125 | return 0; |
1121 | } | 1126 | } |
@@ -1244,7 +1249,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) | |||
1244 | } | 1249 | } |
1245 | } | 1250 | } |
1246 | 1251 | ||
1247 | snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); | 1252 | snd_soc_register_component(&pri_dai->pdev->dev, &samsung_i2s_component, |
1253 | &pri_dai->i2s_dai_drv, 1); | ||
1248 | 1254 | ||
1249 | pm_runtime_enable(&pdev->dev); | 1255 | pm_runtime_enable(&pdev->dev); |
1250 | 1256 | ||
@@ -1283,7 +1289,7 @@ static int samsung_i2s_remove(struct platform_device *pdev) | |||
1283 | i2s->sec_dai = NULL; | 1289 | i2s->sec_dai = NULL; |
1284 | 1290 | ||
1285 | asoc_dma_platform_unregister(&pdev->dev); | 1291 | asoc_dma_platform_unregister(&pdev->dev); |
1286 | snd_soc_unregister_dai(&pdev->dev); | 1292 | snd_soc_unregister_component(&pdev->dev); |
1287 | 1293 | ||
1288 | return 0; | 1294 | return 0; |
1289 | } | 1295 | } |
@@ -1298,7 +1304,7 @@ static struct platform_device_id samsung_i2s_driver_ids[] = { | |||
1298 | }, | 1304 | }, |
1299 | {}, | 1305 | {}, |
1300 | }; | 1306 | }; |
1301 | MODULE_DEVICE_TABLE(platform, samsung-i2s-driver-ids); | 1307 | MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids); |
1302 | 1308 | ||
1303 | #ifdef CONFIG_OF | 1309 | #ifdef CONFIG_OF |
1304 | static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = { | 1310 | static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = { |
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index a07950b0c8ce..6e5fed30aa27 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c | |||
@@ -68,6 +68,8 @@ static struct idma_info { | |||
68 | dma_addr_t lp_tx_addr; | 68 | dma_addr_t lp_tx_addr; |
69 | } idma; | 69 | } idma; |
70 | 70 | ||
71 | static int idma_irq; | ||
72 | |||
71 | static void idma_getpos(dma_addr_t *src) | 73 | static void idma_getpos(dma_addr_t *src) |
72 | { | 74 | { |
73 | *src = idma.lp_tx_addr + | 75 | *src = idma.lp_tx_addr + |
@@ -305,7 +307,7 @@ static int idma_open(struct snd_pcm_substream *substream) | |||
305 | if (prtd == NULL) | 307 | if (prtd == NULL) |
306 | return -ENOMEM; | 308 | return -ENOMEM; |
307 | 309 | ||
308 | ret = request_irq(IRQ_I2S0, iis_irq, 0, "i2s", prtd); | 310 | ret = request_irq(idma_irq, iis_irq, 0, "i2s", prtd); |
309 | if (ret < 0) { | 311 | if (ret < 0) { |
310 | pr_err("fail to claim i2s irq , ret = %d\n", ret); | 312 | pr_err("fail to claim i2s irq , ret = %d\n", ret); |
311 | kfree(prtd); | 313 | kfree(prtd); |
@@ -324,7 +326,7 @@ static int idma_close(struct snd_pcm_substream *substream) | |||
324 | struct snd_pcm_runtime *runtime = substream->runtime; | 326 | struct snd_pcm_runtime *runtime = substream->runtime; |
325 | struct idma_ctrl *prtd = runtime->private_data; | 327 | struct idma_ctrl *prtd = runtime->private_data; |
326 | 328 | ||
327 | free_irq(IRQ_I2S0, prtd); | 329 | free_irq(idma_irq, prtd); |
328 | 330 | ||
329 | if (!prtd) | 331 | if (!prtd) |
330 | pr_err("idma_close called with prtd == NULL\n"); | 332 | pr_err("idma_close called with prtd == NULL\n"); |
@@ -409,6 +411,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr) | |||
409 | idma.regs = regs; | 411 | idma.regs = regs; |
410 | idma.lp_tx_addr = addr; | 412 | idma.lp_tx_addr = addr; |
411 | } | 413 | } |
414 | EXPORT_SYMBOL_GPL(idma_reg_addr_init); | ||
412 | 415 | ||
413 | static struct snd_soc_platform_driver asoc_idma_platform = { | 416 | static struct snd_soc_platform_driver asoc_idma_platform = { |
414 | .ops = &idma_ops, | 417 | .ops = &idma_ops, |
@@ -418,6 +421,10 @@ static struct snd_soc_platform_driver asoc_idma_platform = { | |||
418 | 421 | ||
419 | static int asoc_idma_platform_probe(struct platform_device *pdev) | 422 | static int asoc_idma_platform_probe(struct platform_device *pdev) |
420 | { | 423 | { |
424 | idma_irq = platform_get_irq(pdev, 0); | ||
425 | if (idma_irq < 0) | ||
426 | return idma_irq; | ||
427 | |||
421 | return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); | 428 | return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); |
422 | } | 429 | } |
423 | 430 | ||
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index a301d8cfaa34..e591c386917a 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -21,8 +21,7 @@ | |||
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | 22 | ||
23 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
24 | #include <plat/regs-iis.h> | 24 | #include "regs-iis.h" |
25 | #include <mach/gta02.h> | ||
26 | 25 | ||
27 | #include "../codecs/wm8753.h" | 26 | #include "../codecs/wm8753.h" |
28 | #include "s3c24xx-i2s.h" | 27 | #include "s3c24xx-i2s.h" |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 13bab79ad93d..1566afe9ef52 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -490,6 +490,10 @@ static struct snd_soc_dai_driver s3c_pcm_dai[] = { | |||
490 | }, | 490 | }, |
491 | }; | 491 | }; |
492 | 492 | ||
493 | static const struct snd_soc_component_driver s3c_pcm_component = { | ||
494 | .name = "s3c-pcm", | ||
495 | }; | ||
496 | |||
493 | static int s3c_pcm_dev_probe(struct platform_device *pdev) | 497 | static int s3c_pcm_dev_probe(struct platform_device *pdev) |
494 | { | 498 | { |
495 | struct s3c_pcm_info *pcm; | 499 | struct s3c_pcm_info *pcm; |
@@ -583,7 +587,8 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
583 | 587 | ||
584 | pm_runtime_enable(&pdev->dev); | 588 | pm_runtime_enable(&pdev->dev); |
585 | 589 | ||
586 | ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); | 590 | ret = snd_soc_register_component(&pdev->dev, &s3c_pcm_component, |
591 | &s3c_pcm_dai[pdev->id], 1); | ||
587 | if (ret != 0) { | 592 | if (ret != 0) { |
588 | dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); | 593 | dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); |
589 | goto err5; | 594 | goto err5; |
@@ -598,7 +603,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
598 | return 0; | 603 | return 0; |
599 | 604 | ||
600 | err6: | 605 | err6: |
601 | snd_soc_unregister_dai(&pdev->dev); | 606 | snd_soc_unregister_component(&pdev->dev); |
602 | err5: | 607 | err5: |
603 | clk_disable_unprepare(pcm->pclk); | 608 | clk_disable_unprepare(pcm->pclk); |
604 | clk_put(pcm->pclk); | 609 | clk_put(pcm->pclk); |
@@ -619,7 +624,7 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
619 | struct resource *mem_res; | 624 | struct resource *mem_res; |
620 | 625 | ||
621 | asoc_dma_platform_unregister(&pdev->dev); | 626 | asoc_dma_platform_unregister(&pdev->dev); |
622 | snd_soc_unregister_dai(&pdev->dev); | 627 | snd_soc_unregister_component(&pdev->dev); |
623 | 628 | ||
624 | pm_runtime_disable(&pdev->dev); | 629 | pm_runtime_disable(&pdev->dev); |
625 | 630 | ||
diff --git a/sound/soc/samsung/regs-ac97.h b/sound/soc/samsung/regs-ac97.h new file mode 100644 index 000000000000..c3878f7acb83 --- /dev/null +++ b/sound/soc/samsung/regs-ac97.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* arch/arm/mach-s3c2410/include/mach/regs-ac97.h | ||
2 | * | ||
3 | * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk> | ||
4 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * S3C2440 AC97 Controller | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_REGS_AC97_H | ||
14 | #define __ASM_ARCH_REGS_AC97_H __FILE__ | ||
15 | |||
16 | #define S3C_AC97_GLBCTRL (0x00) | ||
17 | |||
18 | #define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22) | ||
19 | #define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21) | ||
20 | #define S3C_AC97_GLBCTRL_PCMINORIE (1<<20) | ||
21 | #define S3C_AC97_GLBCTRL_MICINORIE (1<<19) | ||
22 | #define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18) | ||
23 | #define S3C_AC97_GLBCTRL_PCMINTIE (1<<17) | ||
24 | #define S3C_AC97_GLBCTRL_MICINTIE (1<<16) | ||
25 | #define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12) | ||
26 | #define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12) | ||
27 | #define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12) | ||
28 | #define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12) | ||
29 | #define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10) | ||
30 | #define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10) | ||
31 | #define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10) | ||
32 | #define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10) | ||
33 | #define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8) | ||
34 | #define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8) | ||
35 | #define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8) | ||
36 | #define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8) | ||
37 | #define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3) | ||
38 | #define S3C_AC97_GLBCTRL_ACLINKON (1<<2) | ||
39 | #define S3C_AC97_GLBCTRL_WARMRESET (1<<1) | ||
40 | #define S3C_AC97_GLBCTRL_COLDRESET (1<<0) | ||
41 | |||
42 | #define S3C_AC97_GLBSTAT (0x04) | ||
43 | |||
44 | #define S3C_AC97_GLBSTAT_CODECREADY (1<<22) | ||
45 | #define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21) | ||
46 | #define S3C_AC97_GLBSTAT_PCMINORI (1<<20) | ||
47 | #define S3C_AC97_GLBSTAT_MICINORI (1<<19) | ||
48 | #define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18) | ||
49 | #define S3C_AC97_GLBSTAT_PCMINTI (1<<17) | ||
50 | #define S3C_AC97_GLBSTAT_MICINTI (1<<16) | ||
51 | #define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0) | ||
52 | #define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0) | ||
53 | #define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0) | ||
54 | #define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0) | ||
55 | #define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0) | ||
56 | #define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0) | ||
57 | |||
58 | #define S3C_AC97_CODEC_CMD (0x08) | ||
59 | |||
60 | #define S3C_AC97_CODEC_CMD_READ (1<<23) | ||
61 | |||
62 | #define S3C_AC97_STAT (0x0c) | ||
63 | #define S3C_AC97_PCM_ADDR (0x10) | ||
64 | #define S3C_AC97_PCM_DATA (0x18) | ||
65 | #define S3C_AC97_MIC_DATA (0x1C) | ||
66 | |||
67 | #endif /* __ASM_ARCH_REGS_AC97_H */ | ||
diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h new file mode 100644 index 000000000000..a18d35e7a735 --- /dev/null +++ b/sound/soc/samsung/regs-iis.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* arch/arm/plat-samsung/include/plat/regs-iis.h | ||
2 | * | ||
3 | * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> | ||
4 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * S3C2410 IIS register definition | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_ARCH_REGS_IIS_H | ||
14 | #define __ASM_ARCH_REGS_IIS_H | ||
15 | |||
16 | #define S3C2410_IISCON (0x00) | ||
17 | |||
18 | #define S3C2410_IISCON_LRINDEX (1 << 8) | ||
19 | #define S3C2410_IISCON_TXFIFORDY (1 << 7) | ||
20 | #define S3C2410_IISCON_RXFIFORDY (1 << 6) | ||
21 | #define S3C2410_IISCON_TXDMAEN (1 << 5) | ||
22 | #define S3C2410_IISCON_RXDMAEN (1 << 4) | ||
23 | #define S3C2410_IISCON_TXIDLE (1 << 3) | ||
24 | #define S3C2410_IISCON_RXIDLE (1 << 2) | ||
25 | #define S3C2410_IISCON_PSCEN (1 << 1) | ||
26 | #define S3C2410_IISCON_IISEN (1 << 0) | ||
27 | |||
28 | #define S3C2410_IISMOD (0x04) | ||
29 | |||
30 | #define S3C2440_IISMOD_MPLL (1 << 9) | ||
31 | #define S3C2410_IISMOD_SLAVE (1 << 8) | ||
32 | #define S3C2410_IISMOD_NOXFER (0 << 6) | ||
33 | #define S3C2410_IISMOD_RXMODE (1 << 6) | ||
34 | #define S3C2410_IISMOD_TXMODE (2 << 6) | ||
35 | #define S3C2410_IISMOD_TXRXMODE (3 << 6) | ||
36 | #define S3C2410_IISMOD_LR_LLOW (0 << 5) | ||
37 | #define S3C2410_IISMOD_LR_RLOW (1 << 5) | ||
38 | #define S3C2410_IISMOD_IIS (0 << 4) | ||
39 | #define S3C2410_IISMOD_MSB (1 << 4) | ||
40 | #define S3C2410_IISMOD_8BIT (0 << 3) | ||
41 | #define S3C2410_IISMOD_16BIT (1 << 3) | ||
42 | #define S3C2410_IISMOD_BITMASK (1 << 3) | ||
43 | #define S3C2410_IISMOD_256FS (0 << 2) | ||
44 | #define S3C2410_IISMOD_384FS (1 << 2) | ||
45 | #define S3C2410_IISMOD_16FS (0 << 0) | ||
46 | #define S3C2410_IISMOD_32FS (1 << 0) | ||
47 | #define S3C2410_IISMOD_48FS (2 << 0) | ||
48 | #define S3C2410_IISMOD_FS_MASK (3 << 0) | ||
49 | |||
50 | #define S3C2410_IISPSR (0x08) | ||
51 | |||
52 | #define S3C2410_IISPSR_INTMASK (31 << 5) | ||
53 | #define S3C2410_IISPSR_INTSHIFT (5) | ||
54 | #define S3C2410_IISPSR_EXTMASK (31 << 0) | ||
55 | #define S3C2410_IISPSR_EXTSHFIT (0) | ||
56 | |||
57 | #define S3C2410_IISFCON (0x0c) | ||
58 | |||
59 | #define S3C2410_IISFCON_TXDMA (1 << 15) | ||
60 | #define S3C2410_IISFCON_RXDMA (1 << 14) | ||
61 | #define S3C2410_IISFCON_TXENABLE (1 << 13) | ||
62 | #define S3C2410_IISFCON_RXENABLE (1 << 12) | ||
63 | #define S3C2410_IISFCON_TXMASK (0x3f << 6) | ||
64 | #define S3C2410_IISFCON_TXSHIFT (6) | ||
65 | #define S3C2410_IISFCON_RXMASK (0x3f) | ||
66 | #define S3C2410_IISFCON_RXSHIFT (0) | ||
67 | |||
68 | #define S3C2410_IISFIFO (0x10) | ||
69 | |||
70 | #endif /* __ASM_ARCH_REGS_IIS_H */ | ||
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index a5826ea9cad6..704460a37005 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/jack.h> | 25 | #include <sound/jack.h> |
26 | 26 | ||
27 | #include <plat/regs-iis.h> | 27 | #include "regs-iis.h" |
28 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
29 | 29 | ||
30 | #include "s3c24xx-i2s.h" | 30 | #include "s3c24xx-i2s.h" |
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 7a73380b3560..20e98d1dded2 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
@@ -731,8 +731,9 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai) | |||
731 | #define s3c2412_i2s_resume NULL | 731 | #define s3c2412_i2s_resume NULL |
732 | #endif | 732 | #endif |
733 | 733 | ||
734 | int s3c_i2sv2_register_dai(struct device *dev, int id, | 734 | int s3c_i2sv2_register_component(struct device *dev, int id, |
735 | struct snd_soc_dai_driver *drv) | 735 | struct snd_soc_component_driver *cmp_drv, |
736 | struct snd_soc_dai_driver *dai_drv) | ||
736 | { | 737 | { |
737 | struct snd_soc_dai_ops *ops = drv->ops; | 738 | struct snd_soc_dai_ops *ops = drv->ops; |
738 | 739 | ||
@@ -750,8 +751,8 @@ int s3c_i2sv2_register_dai(struct device *dev, int id, | |||
750 | drv->suspend = s3c2412_i2s_suspend; | 751 | drv->suspend = s3c2412_i2s_suspend; |
751 | drv->resume = s3c2412_i2s_resume; | 752 | drv->resume = s3c2412_i2s_resume; |
752 | 753 | ||
753 | return snd_soc_register_dai(dev, drv); | 754 | return snd_soc_register_component(dev, cmp_drv, dai_drv, 1); |
754 | } | 755 | } |
755 | EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); | 756 | EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); |
756 | 757 | ||
757 | MODULE_LICENSE("GPL"); | 758 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index f8297d9bb8a3..90abab364b49 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h | |||
@@ -92,7 +92,7 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, | |||
92 | unsigned long base); | 92 | unsigned long base); |
93 | 93 | ||
94 | /** | 94 | /** |
95 | * s3c_i2sv2_register_dai - register dai with soc core | 95 | * s3c_i2sv2_register_component - register component and dai with soc core |
96 | * @dev: DAI device | 96 | * @dev: DAI device |
97 | * @id: DAI ID | 97 | * @id: DAI ID |
98 | * @drv: The driver structure to register | 98 | * @drv: The driver structure to register |
@@ -100,7 +100,8 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, | |||
100 | * Fill in any missing fields and then register the given dai with the | 100 | * Fill in any missing fields and then register the given dai with the |
101 | * soc core. | 101 | * soc core. |
102 | */ | 102 | */ |
103 | extern int s3c_i2sv2_register_dai(struct device *dev, int id, | 103 | extern int s3c_i2sv2_register_component(struct device *dev, int id, |
104 | struct snd_soc_dai_driver *drv); | 104 | struct snd_soc_component_driver *cmp_drv, |
105 | struct snd_soc_dai_driver *dai_drv); | ||
105 | 106 | ||
106 | #endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ | 107 | #endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 221337716393..47e23864ea72 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
@@ -160,11 +160,17 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { | |||
160 | .ops = &s3c2412_i2s_dai_ops, | 160 | .ops = &s3c2412_i2s_dai_ops, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static const struct snd_soc_component_driver s3c2412_i2s_component = { | ||
164 | .name = "s3c2412-i2s", | ||
165 | }; | ||
166 | |||
163 | static int s3c2412_iis_dev_probe(struct platform_device *pdev) | 167 | static int s3c2412_iis_dev_probe(struct platform_device *pdev) |
164 | { | 168 | { |
165 | int ret = 0; | 169 | int ret = 0; |
166 | 170 | ||
167 | ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); | 171 | ret = s3c_i2sv2_register_component(&pdev->dev, -1, |
172 | &s3c2412_i2s_component, | ||
173 | &s3c2412_i2s_dai); | ||
168 | if (ret) { | 174 | if (ret) { |
169 | pr_err("failed to register the dai\n"); | 175 | pr_err("failed to register the dai\n"); |
170 | return ret; | 176 | return ret; |
@@ -178,14 +184,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) | |||
178 | 184 | ||
179 | return 0; | 185 | return 0; |
180 | err: | 186 | err: |
181 | snd_soc_unregister_dai(&pdev->dev); | 187 | snd_soc_unregister_component(&pdev->dev); |
182 | return ret; | 188 | return ret; |
183 | } | 189 | } |
184 | 190 | ||
185 | static int s3c2412_iis_dev_remove(struct platform_device *pdev) | 191 | static int s3c2412_iis_dev_remove(struct platform_device *pdev) |
186 | { | 192 | { |
187 | asoc_dma_platform_unregister(&pdev->dev); | 193 | asoc_dma_platform_unregister(&pdev->dev); |
188 | snd_soc_unregister_dai(&pdev->dev); | 194 | snd_soc_unregister_component(&pdev->dev); |
189 | return 0; | 195 | return 0; |
190 | } | 196 | } |
191 | 197 | ||
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 13f6dd1ceb00..8b3414551a62 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/pcm_params.h> | 24 | #include <sound/pcm_params.h> |
25 | 25 | ||
26 | #include <mach/dma.h> | 26 | #include <mach/dma.h> |
27 | #include <plat/regs-iis.h> | 27 | #include "regs-iis.h" |
28 | 28 | ||
29 | #include "dma.h" | 29 | #include "dma.h" |
30 | #include "s3c24xx-i2s.h" | 30 | #include "s3c24xx-i2s.h" |
@@ -465,11 +465,16 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = { | |||
465 | .ops = &s3c24xx_i2s_dai_ops, | 465 | .ops = &s3c24xx_i2s_dai_ops, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static const struct snd_soc_component_driver s3c24xx_i2s_component = { | ||
469 | .name = "s3c24xx-i2s", | ||
470 | }; | ||
471 | |||
468 | static int s3c24xx_iis_dev_probe(struct platform_device *pdev) | 472 | static int s3c24xx_iis_dev_probe(struct platform_device *pdev) |
469 | { | 473 | { |
470 | int ret = 0; | 474 | int ret = 0; |
471 | 475 | ||
472 | ret = snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); | 476 | ret = snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component, |
477 | &s3c24xx_i2s_dai, 1); | ||
473 | if (ret) { | 478 | if (ret) { |
474 | pr_err("failed to register the dai\n"); | 479 | pr_err("failed to register the dai\n"); |
475 | return ret; | 480 | return ret; |
@@ -483,14 +488,14 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) | |||
483 | 488 | ||
484 | return 0; | 489 | return 0; |
485 | err: | 490 | err: |
486 | snd_soc_unregister_dai(&pdev->dev); | 491 | snd_soc_unregister_component(&pdev->dev); |
487 | return ret; | 492 | return ret; |
488 | } | 493 | } |
489 | 494 | ||
490 | static int s3c24xx_iis_dev_remove(struct platform_device *pdev) | 495 | static int s3c24xx_iis_dev_remove(struct platform_device *pdev) |
491 | { | 496 | { |
492 | asoc_dma_platform_unregister(&pdev->dev); | 497 | asoc_dma_platform_unregister(&pdev->dev); |
493 | snd_soc_unregister_dai(&pdev->dev); | 498 | snd_soc_unregister_component(&pdev->dev); |
494 | return 0; | 499 | return 0; |
495 | } | 500 | } |
496 | 501 | ||
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 333e1b7f06c7..1b7b52b0af97 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | #include <sound/s3c24xx_uda134x.h> | 19 | #include <sound/s3c24xx_uda134x.h> |
20 | 20 | ||
21 | #include <plat/regs-iis.h> | 21 | #include "regs-iis.h" |
22 | 22 | ||
23 | #include "s3c24xx-i2s.h" | 23 | #include "s3c24xx-i2s.h" |
24 | 24 | ||
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 5008e5bd6ed8..2e5ebb2f1982 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -357,6 +357,10 @@ static struct snd_soc_dai_driver samsung_spdif_dai = { | |||
357 | .resume = spdif_resume, | 357 | .resume = spdif_resume, |
358 | }; | 358 | }; |
359 | 359 | ||
360 | static const struct snd_soc_component_driver samsung_spdif_component = { | ||
361 | .name = "samsung-spdif", | ||
362 | }; | ||
363 | |||
360 | static int spdif_probe(struct platform_device *pdev) | 364 | static int spdif_probe(struct platform_device *pdev) |
361 | { | 365 | { |
362 | struct s3c_audio_pdata *spdif_pdata; | 366 | struct s3c_audio_pdata *spdif_pdata; |
@@ -424,7 +428,8 @@ static int spdif_probe(struct platform_device *pdev) | |||
424 | 428 | ||
425 | dev_set_drvdata(&pdev->dev, spdif); | 429 | dev_set_drvdata(&pdev->dev, spdif); |
426 | 430 | ||
427 | ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai); | 431 | ret = snd_soc_register_component(&pdev->dev, &samsung_spdif_component, |
432 | &samsung_spdif_dai, 1); | ||
428 | if (ret != 0) { | 433 | if (ret != 0) { |
429 | dev_err(&pdev->dev, "fail to register dai\n"); | 434 | dev_err(&pdev->dev, "fail to register dai\n"); |
430 | goto err4; | 435 | goto err4; |
@@ -445,7 +450,7 @@ static int spdif_probe(struct platform_device *pdev) | |||
445 | 450 | ||
446 | return 0; | 451 | return 0; |
447 | err5: | 452 | err5: |
448 | snd_soc_unregister_dai(&pdev->dev); | 453 | snd_soc_unregister_component(&pdev->dev); |
449 | err4: | 454 | err4: |
450 | iounmap(spdif->regs); | 455 | iounmap(spdif->regs); |
451 | err3: | 456 | err3: |
@@ -466,7 +471,7 @@ static int spdif_remove(struct platform_device *pdev) | |||
466 | struct resource *mem_res; | 471 | struct resource *mem_res; |
467 | 472 | ||
468 | asoc_dma_platform_unregister(&pdev->dev); | 473 | asoc_dma_platform_unregister(&pdev->dev); |
469 | snd_soc_unregister_dai(&pdev->dev); | 474 | snd_soc_unregister_component(&pdev->dev); |
470 | 475 | ||
471 | iounmap(spdif->regs); | 476 | iounmap(spdif->regs); |
472 | 477 | ||
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index c724026a246f..f830c41f97dd 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -296,7 +296,6 @@ struct fsi_core { | |||
296 | 296 | ||
297 | struct fsi_master { | 297 | struct fsi_master { |
298 | void __iomem *base; | 298 | void __iomem *base; |
299 | int irq; | ||
300 | struct fsi_priv fsia; | 299 | struct fsi_priv fsia; |
301 | struct fsi_priv fsib; | 300 | struct fsi_priv fsib; |
302 | const struct fsi_core *core; | 301 | const struct fsi_core *core; |
@@ -1886,6 +1885,10 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
1886 | .pcm_free = fsi_pcm_free, | 1885 | .pcm_free = fsi_pcm_free, |
1887 | }; | 1886 | }; |
1888 | 1887 | ||
1888 | static const struct snd_soc_component_driver fsi_soc_component = { | ||
1889 | .name = "fsi", | ||
1890 | }; | ||
1891 | |||
1889 | /* | 1892 | /* |
1890 | * platform function | 1893 | * platform function |
1891 | */ | 1894 | */ |
@@ -2002,7 +2005,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
2002 | } | 2005 | } |
2003 | 2006 | ||
2004 | /* master setting */ | 2007 | /* master setting */ |
2005 | master->irq = irq; | ||
2006 | master->core = core; | 2008 | master->core = core; |
2007 | spin_lock_init(&master->lock); | 2009 | spin_lock_init(&master->lock); |
2008 | 2010 | ||
@@ -2046,10 +2048,10 @@ static int fsi_probe(struct platform_device *pdev) | |||
2046 | goto exit_fsib; | 2048 | goto exit_fsib; |
2047 | } | 2049 | } |
2048 | 2050 | ||
2049 | ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, | 2051 | ret = snd_soc_register_component(&pdev->dev, &fsi_soc_component, |
2050 | ARRAY_SIZE(fsi_soc_dai)); | 2052 | fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); |
2051 | if (ret < 0) { | 2053 | if (ret < 0) { |
2052 | dev_err(&pdev->dev, "cannot snd dai register\n"); | 2054 | dev_err(&pdev->dev, "cannot snd component register\n"); |
2053 | goto exit_snd_soc; | 2055 | goto exit_snd_soc; |
2054 | } | 2056 | } |
2055 | 2057 | ||
@@ -2074,7 +2076,7 @@ static int fsi_remove(struct platform_device *pdev) | |||
2074 | 2076 | ||
2075 | pm_runtime_disable(&pdev->dev); | 2077 | pm_runtime_disable(&pdev->dev); |
2076 | 2078 | ||
2077 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 2079 | snd_soc_unregister_component(&pdev->dev); |
2078 | snd_soc_unregister_platform(&pdev->dev); | 2080 | snd_soc_unregister_platform(&pdev->dev); |
2079 | 2081 | ||
2080 | fsi_stream_remove(&master->fsia); | 2082 | fsi_stream_remove(&master->fsia); |
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 4cc2d64ef476..af19f77b7bf0 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c | |||
@@ -310,15 +310,19 @@ static struct snd_soc_dai_driver sh4_hac_dai[] = { | |||
310 | #endif | 310 | #endif |
311 | }; | 311 | }; |
312 | 312 | ||
313 | static const struct snd_soc_component_driver sh4_hac_component = { | ||
314 | .name = "sh4-hac", | ||
315 | }; | ||
316 | |||
313 | static int hac_soc_platform_probe(struct platform_device *pdev) | 317 | static int hac_soc_platform_probe(struct platform_device *pdev) |
314 | { | 318 | { |
315 | return snd_soc_register_dais(&pdev->dev, sh4_hac_dai, | 319 | return snd_soc_register_component(&pdev->dev, &sh4_hac_component, |
316 | ARRAY_SIZE(sh4_hac_dai)); | 320 | sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); |
317 | } | 321 | } |
318 | 322 | ||
319 | static int hac_soc_platform_remove(struct platform_device *pdev) | 323 | static int hac_soc_platform_remove(struct platform_device *pdev) |
320 | { | 324 | { |
321 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai)); | 325 | snd_soc_unregister_component(&pdev->dev); |
322 | return 0; | 326 | return 0; |
323 | } | 327 | } |
324 | 328 | ||
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 8526e1edaf45..5014a884afee 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c | |||
@@ -153,7 +153,7 @@ static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
153 | static struct snd_soc_dai_link migor_dai = { | 153 | static struct snd_soc_dai_link migor_dai = { |
154 | .name = "wm8978", | 154 | .name = "wm8978", |
155 | .stream_name = "WM8978", | 155 | .stream_name = "WM8978", |
156 | .cpu_dai_name = "siu-i2s-dai", | 156 | .cpu_dai_name = "siu-pcm-audio", |
157 | .codec_dai_name = "wm8978-hifi", | 157 | .codec_dai_name = "wm8978-hifi", |
158 | .platform_name = "siu-pcm-audio", | 158 | .platform_name = "siu-pcm-audio", |
159 | .codec_name = "wm8978.0-001a", | 159 | .codec_name = "wm8978.0-001a", |
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 34facdc9e4ac..9dc24ffa892a 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c | |||
@@ -726,6 +726,10 @@ static struct snd_soc_dai_driver siu_i2s_dai = { | |||
726 | .ops = &siu_dai_ops, | 726 | .ops = &siu_dai_ops, |
727 | }; | 727 | }; |
728 | 728 | ||
729 | static const struct snd_soc_component_driver siu_i2s_component = { | ||
730 | .name = "siu-i2s", | ||
731 | }; | ||
732 | |||
729 | static int siu_probe(struct platform_device *pdev) | 733 | static int siu_probe(struct platform_device *pdev) |
730 | { | 734 | { |
731 | const struct firmware *fw_entry; | 735 | const struct firmware *fw_entry; |
@@ -783,7 +787,8 @@ static int siu_probe(struct platform_device *pdev) | |||
783 | dev_set_drvdata(&pdev->dev, info); | 787 | dev_set_drvdata(&pdev->dev, info); |
784 | 788 | ||
785 | /* register using ARRAY version so we can keep dai name */ | 789 | /* register using ARRAY version so we can keep dai name */ |
786 | ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1); | 790 | ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component, |
791 | &siu_i2s_dai, 1); | ||
787 | if (ret < 0) | 792 | if (ret < 0) |
788 | goto edaiinit; | 793 | goto edaiinit; |
789 | 794 | ||
@@ -796,7 +801,7 @@ static int siu_probe(struct platform_device *pdev) | |||
796 | return ret; | 801 | return ret; |
797 | 802 | ||
798 | esocregp: | 803 | esocregp: |
799 | snd_soc_unregister_dai(&pdev->dev); | 804 | snd_soc_unregister_component(&pdev->dev); |
800 | edaiinit: | 805 | edaiinit: |
801 | iounmap(info->reg); | 806 | iounmap(info->reg); |
802 | emapreg: | 807 | emapreg: |
@@ -823,7 +828,7 @@ static int siu_remove(struct platform_device *pdev) | |||
823 | pm_runtime_disable(&pdev->dev); | 828 | pm_runtime_disable(&pdev->dev); |
824 | 829 | ||
825 | snd_soc_unregister_platform(&pdev->dev); | 830 | snd_soc_unregister_platform(&pdev->dev); |
826 | snd_soc_unregister_dai(&pdev->dev); | 831 | snd_soc_unregister_component(&pdev->dev); |
827 | 832 | ||
828 | iounmap(info->reg); | 833 | iounmap(info->reg); |
829 | iounmap(info->yram); | 834 | iounmap(info->yram); |
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index c8e73a703934..e889405ebd38 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c | |||
@@ -379,15 +379,19 @@ static struct snd_soc_dai_driver sh4_ssi_dai[] = { | |||
379 | #endif | 379 | #endif |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static const struct snd_soc_component_driver sh4_ssi_component = { | ||
383 | .name = "sh4-ssi", | ||
384 | }; | ||
385 | |||
382 | static int sh4_soc_dai_probe(struct platform_device *pdev) | 386 | static int sh4_soc_dai_probe(struct platform_device *pdev) |
383 | { | 387 | { |
384 | return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai, | 388 | return snd_soc_register_component(&pdev->dev, &sh4_ssi_component, |
385 | ARRAY_SIZE(sh4_ssi_dai)); | 389 | sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); |
386 | } | 390 | } |
387 | 391 | ||
388 | static int sh4_soc_dai_remove(struct platform_device *pdev) | 392 | static int sh4_soc_dai_remove(struct platform_device *pdev) |
389 | { | 393 | { |
390 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai)); | 394 | snd_soc_unregister_component(&pdev->dev); |
391 | return 0; | 395 | return 0; |
392 | } | 396 | } |
393 | 397 | ||
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index ed0bfb0ddb96..3853f7eb3f28 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -315,7 +315,7 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream, | |||
315 | } | 315 | } |
316 | 316 | ||
317 | static int soc_compr_copy(struct snd_compr_stream *cstream, | 317 | static int soc_compr_copy(struct snd_compr_stream *cstream, |
318 | const char __user *buf, size_t count) | 318 | char __user *buf, size_t count) |
319 | { | 319 | { |
320 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | 320 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; |
321 | struct snd_soc_platform *platform = rtd->platform; | 321 | struct snd_soc_platform *platform = rtd->platform; |
@@ -330,11 +330,38 @@ static int soc_compr_copy(struct snd_compr_stream *cstream, | |||
330 | return ret; | 330 | return ret; |
331 | } | 331 | } |
332 | 332 | ||
333 | static int sst_compr_set_metadata(struct snd_compr_stream *cstream, | ||
334 | struct snd_compr_metadata *metadata) | ||
335 | { | ||
336 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
337 | struct snd_soc_platform *platform = rtd->platform; | ||
338 | int ret = 0; | ||
339 | |||
340 | if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) | ||
341 | ret = platform->driver->compr_ops->set_metadata(cstream, metadata); | ||
342 | |||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static int sst_compr_get_metadata(struct snd_compr_stream *cstream, | ||
347 | struct snd_compr_metadata *metadata) | ||
348 | { | ||
349 | struct snd_soc_pcm_runtime *rtd = cstream->private_data; | ||
350 | struct snd_soc_platform *platform = rtd->platform; | ||
351 | int ret = 0; | ||
352 | |||
353 | if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) | ||
354 | ret = platform->driver->compr_ops->get_metadata(cstream, metadata); | ||
355 | |||
356 | return ret; | ||
357 | } | ||
333 | /* ASoC Compress operations */ | 358 | /* ASoC Compress operations */ |
334 | static struct snd_compr_ops soc_compr_ops = { | 359 | static struct snd_compr_ops soc_compr_ops = { |
335 | .open = soc_compr_open, | 360 | .open = soc_compr_open, |
336 | .free = soc_compr_free, | 361 | .free = soc_compr_free, |
337 | .set_params = soc_compr_set_params, | 362 | .set_params = soc_compr_set_params, |
363 | .set_metadata = sst_compr_set_metadata, | ||
364 | .get_metadata = sst_compr_get_metadata, | ||
338 | .get_params = soc_compr_get_params, | 365 | .get_params = soc_compr_get_params, |
339 | .trigger = soc_compr_trigger, | 366 | .trigger = soc_compr_trigger, |
340 | .pointer = soc_compr_pointer, | 367 | .pointer = soc_compr_pointer, |
@@ -357,7 +384,14 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | |||
357 | /* check client and interface hw capabilities */ | 384 | /* check client and interface hw capabilities */ |
358 | snprintf(new_name, sizeof(new_name), "%s %s-%d", | 385 | snprintf(new_name, sizeof(new_name), "%s %s-%d", |
359 | rtd->dai_link->stream_name, codec_dai->name, num); | 386 | rtd->dai_link->stream_name, codec_dai->name, num); |
360 | direction = SND_COMPRESS_PLAYBACK; | 387 | |
388 | if (codec_dai->driver->playback.channels_min) | ||
389 | direction = SND_COMPRESS_PLAYBACK; | ||
390 | else if (codec_dai->driver->capture.channels_min) | ||
391 | direction = SND_COMPRESS_CAPTURE; | ||
392 | else | ||
393 | return -EINVAL; | ||
394 | |||
361 | compr = kzalloc(sizeof(*compr), GFP_KERNEL); | 395 | compr = kzalloc(sizeof(*compr), GFP_KERNEL); |
362 | if (compr == NULL) { | 396 | if (compr == NULL) { |
363 | snd_printk(KERN_ERR "Cannot allocate compr\n"); | 397 | snd_printk(KERN_ERR "Cannot allocate compr\n"); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ff4b45a5d796..d56bbea6e75e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -58,6 +58,7 @@ static DEFINE_MUTEX(client_mutex); | |||
58 | static LIST_HEAD(dai_list); | 58 | static LIST_HEAD(dai_list); |
59 | static LIST_HEAD(platform_list); | 59 | static LIST_HEAD(platform_list); |
60 | static LIST_HEAD(codec_list); | 60 | static LIST_HEAD(codec_list); |
61 | static LIST_HEAD(component_list); | ||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * This is a timeout to do a DAPM powerdown after a stream is closed(). | 64 | * This is a timeout to do a DAPM powerdown after a stream is closed(). |
@@ -3740,7 +3741,7 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
3740 | * | 3741 | * |
3741 | * @dai: DAI to register | 3742 | * @dai: DAI to register |
3742 | */ | 3743 | */ |
3743 | int snd_soc_register_dai(struct device *dev, | 3744 | static int snd_soc_register_dai(struct device *dev, |
3744 | struct snd_soc_dai_driver *dai_drv) | 3745 | struct snd_soc_dai_driver *dai_drv) |
3745 | { | 3746 | { |
3746 | struct snd_soc_codec *codec; | 3747 | struct snd_soc_codec *codec; |
@@ -3787,14 +3788,13 @@ int snd_soc_register_dai(struct device *dev, | |||
3787 | 3788 | ||
3788 | return 0; | 3789 | return 0; |
3789 | } | 3790 | } |
3790 | EXPORT_SYMBOL_GPL(snd_soc_register_dai); | ||
3791 | 3791 | ||
3792 | /** | 3792 | /** |
3793 | * snd_soc_unregister_dai - Unregister a DAI from the ASoC core | 3793 | * snd_soc_unregister_dai - Unregister a DAI from the ASoC core |
3794 | * | 3794 | * |
3795 | * @dai: DAI to unregister | 3795 | * @dai: DAI to unregister |
3796 | */ | 3796 | */ |
3797 | void snd_soc_unregister_dai(struct device *dev) | 3797 | static void snd_soc_unregister_dai(struct device *dev) |
3798 | { | 3798 | { |
3799 | struct snd_soc_dai *dai; | 3799 | struct snd_soc_dai *dai; |
3800 | 3800 | ||
@@ -3813,7 +3813,6 @@ found: | |||
3813 | kfree(dai->name); | 3813 | kfree(dai->name); |
3814 | kfree(dai); | 3814 | kfree(dai); |
3815 | } | 3815 | } |
3816 | EXPORT_SYMBOL_GPL(snd_soc_unregister_dai); | ||
3817 | 3816 | ||
3818 | /** | 3817 | /** |
3819 | * snd_soc_register_dais - Register multiple DAIs with the ASoC core | 3818 | * snd_soc_register_dais - Register multiple DAIs with the ASoC core |
@@ -3821,7 +3820,7 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dai); | |||
3821 | * @dai: Array of DAIs to register | 3820 | * @dai: Array of DAIs to register |
3822 | * @count: Number of DAIs | 3821 | * @count: Number of DAIs |
3823 | */ | 3822 | */ |
3824 | int snd_soc_register_dais(struct device *dev, | 3823 | static int snd_soc_register_dais(struct device *dev, |
3825 | struct snd_soc_dai_driver *dai_drv, size_t count) | 3824 | struct snd_soc_dai_driver *dai_drv, size_t count) |
3826 | { | 3825 | { |
3827 | struct snd_soc_codec *codec; | 3826 | struct snd_soc_codec *codec; |
@@ -3885,7 +3884,6 @@ err: | |||
3885 | 3884 | ||
3886 | return ret; | 3885 | return ret; |
3887 | } | 3886 | } |
3888 | EXPORT_SYMBOL_GPL(snd_soc_register_dais); | ||
3889 | 3887 | ||
3890 | /** | 3888 | /** |
3891 | * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core | 3889 | * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core |
@@ -3893,31 +3891,23 @@ EXPORT_SYMBOL_GPL(snd_soc_register_dais); | |||
3893 | * @dai: Array of DAIs to unregister | 3891 | * @dai: Array of DAIs to unregister |
3894 | * @count: Number of DAIs | 3892 | * @count: Number of DAIs |
3895 | */ | 3893 | */ |
3896 | void snd_soc_unregister_dais(struct device *dev, size_t count) | 3894 | static void snd_soc_unregister_dais(struct device *dev, size_t count) |
3897 | { | 3895 | { |
3898 | int i; | 3896 | int i; |
3899 | 3897 | ||
3900 | for (i = 0; i < count; i++) | 3898 | for (i = 0; i < count; i++) |
3901 | snd_soc_unregister_dai(dev); | 3899 | snd_soc_unregister_dai(dev); |
3902 | } | 3900 | } |
3903 | EXPORT_SYMBOL_GPL(snd_soc_unregister_dais); | ||
3904 | 3901 | ||
3905 | /** | 3902 | /** |
3906 | * snd_soc_register_platform - Register a platform with the ASoC core | 3903 | * snd_soc_add_platform - Add a platform to the ASoC core |
3907 | * | 3904 | * @dev: The parent device for the platform |
3908 | * @platform: platform to register | 3905 | * @platform: The platform to add |
3906 | * @platform_driver: The driver for the platform | ||
3909 | */ | 3907 | */ |
3910 | int snd_soc_register_platform(struct device *dev, | 3908 | int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, |
3911 | struct snd_soc_platform_driver *platform_drv) | 3909 | const struct snd_soc_platform_driver *platform_drv) |
3912 | { | 3910 | { |
3913 | struct snd_soc_platform *platform; | ||
3914 | |||
3915 | dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev)); | ||
3916 | |||
3917 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); | ||
3918 | if (platform == NULL) | ||
3919 | return -ENOMEM; | ||
3920 | |||
3921 | /* create platform component name */ | 3911 | /* create platform component name */ |
3922 | platform->name = fmt_single_name(dev, &platform->id); | 3912 | platform->name = fmt_single_name(dev, &platform->id); |
3923 | if (platform->name == NULL) { | 3913 | if (platform->name == NULL) { |
@@ -3940,30 +3930,76 @@ int snd_soc_register_platform(struct device *dev, | |||
3940 | 3930 | ||
3941 | return 0; | 3931 | return 0; |
3942 | } | 3932 | } |
3943 | EXPORT_SYMBOL_GPL(snd_soc_register_platform); | 3933 | EXPORT_SYMBOL_GPL(snd_soc_add_platform); |
3944 | 3934 | ||
3945 | /** | 3935 | /** |
3946 | * snd_soc_unregister_platform - Unregister a platform from the ASoC core | 3936 | * snd_soc_register_platform - Register a platform with the ASoC core |
3947 | * | 3937 | * |
3948 | * @platform: platform to unregister | 3938 | * @platform: platform to register |
3949 | */ | 3939 | */ |
3950 | void snd_soc_unregister_platform(struct device *dev) | 3940 | int snd_soc_register_platform(struct device *dev, |
3941 | const struct snd_soc_platform_driver *platform_drv) | ||
3951 | { | 3942 | { |
3952 | struct snd_soc_platform *platform; | 3943 | struct snd_soc_platform *platform; |
3944 | int ret; | ||
3953 | 3945 | ||
3954 | list_for_each_entry(platform, &platform_list, list) { | 3946 | dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev)); |
3955 | if (dev == platform->dev) | ||
3956 | goto found; | ||
3957 | } | ||
3958 | return; | ||
3959 | 3947 | ||
3960 | found: | 3948 | platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL); |
3949 | if (platform == NULL) | ||
3950 | return -ENOMEM; | ||
3951 | |||
3952 | ret = snd_soc_add_platform(dev, platform, platform_drv); | ||
3953 | if (ret) | ||
3954 | kfree(platform); | ||
3955 | |||
3956 | return ret; | ||
3957 | } | ||
3958 | EXPORT_SYMBOL_GPL(snd_soc_register_platform); | ||
3959 | |||
3960 | /** | ||
3961 | * snd_soc_remove_platform - Remove a platform from the ASoC core | ||
3962 | * @platform: the platform to remove | ||
3963 | */ | ||
3964 | void snd_soc_remove_platform(struct snd_soc_platform *platform) | ||
3965 | { | ||
3961 | mutex_lock(&client_mutex); | 3966 | mutex_lock(&client_mutex); |
3962 | list_del(&platform->list); | 3967 | list_del(&platform->list); |
3963 | mutex_unlock(&client_mutex); | 3968 | mutex_unlock(&client_mutex); |
3964 | 3969 | ||
3965 | dev_dbg(dev, "ASoC: Unregistered platform '%s'\n", platform->name); | 3970 | dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n", |
3971 | platform->name); | ||
3966 | kfree(platform->name); | 3972 | kfree(platform->name); |
3973 | } | ||
3974 | EXPORT_SYMBOL_GPL(snd_soc_remove_platform); | ||
3975 | |||
3976 | struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev) | ||
3977 | { | ||
3978 | struct snd_soc_platform *platform; | ||
3979 | |||
3980 | list_for_each_entry(platform, &platform_list, list) { | ||
3981 | if (dev == platform->dev) | ||
3982 | return platform; | ||
3983 | } | ||
3984 | |||
3985 | return NULL; | ||
3986 | } | ||
3987 | EXPORT_SYMBOL_GPL(snd_soc_lookup_platform); | ||
3988 | |||
3989 | /** | ||
3990 | * snd_soc_unregister_platform - Unregister a platform from the ASoC core | ||
3991 | * | ||
3992 | * @platform: platform to unregister | ||
3993 | */ | ||
3994 | void snd_soc_unregister_platform(struct device *dev) | ||
3995 | { | ||
3996 | struct snd_soc_platform *platform; | ||
3997 | |||
3998 | platform = snd_soc_lookup_platform(dev); | ||
3999 | if (!platform) | ||
4000 | return; | ||
4001 | |||
4002 | snd_soc_remove_platform(platform); | ||
3967 | kfree(platform); | 4003 | kfree(platform); |
3968 | } | 4004 | } |
3969 | EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); | 4005 | EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); |
@@ -4024,8 +4060,8 @@ int snd_soc_register_codec(struct device *dev, | |||
4024 | /* create CODEC component name */ | 4060 | /* create CODEC component name */ |
4025 | codec->name = fmt_single_name(dev, &codec->id); | 4061 | codec->name = fmt_single_name(dev, &codec->id); |
4026 | if (codec->name == NULL) { | 4062 | if (codec->name == NULL) { |
4027 | kfree(codec); | 4063 | ret = -ENOMEM; |
4028 | return -ENOMEM; | 4064 | goto fail_codec; |
4029 | } | 4065 | } |
4030 | 4066 | ||
4031 | if (codec_drv->compress_type) | 4067 | if (codec_drv->compress_type) |
@@ -4064,7 +4100,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4064 | reg_size, GFP_KERNEL); | 4100 | reg_size, GFP_KERNEL); |
4065 | if (!codec->reg_def_copy) { | 4101 | if (!codec->reg_def_copy) { |
4066 | ret = -ENOMEM; | 4102 | ret = -ENOMEM; |
4067 | goto fail; | 4103 | goto fail_codec_name; |
4068 | } | 4104 | } |
4069 | } | 4105 | } |
4070 | } | 4106 | } |
@@ -4088,18 +4124,22 @@ int snd_soc_register_codec(struct device *dev, | |||
4088 | mutex_unlock(&client_mutex); | 4124 | mutex_unlock(&client_mutex); |
4089 | 4125 | ||
4090 | /* register any DAIs */ | 4126 | /* register any DAIs */ |
4091 | if (num_dai) { | 4127 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); |
4092 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | 4128 | if (ret < 0) { |
4093 | if (ret < 0) | 4129 | dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret); |
4094 | dev_err(codec->dev, "ASoC: Failed to regster" | 4130 | goto fail_codec_name; |
4095 | " DAIs: %d\n", ret); | ||
4096 | } | 4131 | } |
4097 | 4132 | ||
4098 | dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); | 4133 | dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name); |
4099 | return 0; | 4134 | return 0; |
4100 | 4135 | ||
4101 | fail: | 4136 | fail_codec_name: |
4137 | mutex_lock(&client_mutex); | ||
4138 | list_del(&codec->list); | ||
4139 | mutex_unlock(&client_mutex); | ||
4140 | |||
4102 | kfree(codec->name); | 4141 | kfree(codec->name); |
4142 | fail_codec: | ||
4103 | kfree(codec); | 4143 | kfree(codec); |
4104 | return ret; | 4144 | return ret; |
4105 | } | 4145 | } |
@@ -4113,7 +4153,6 @@ EXPORT_SYMBOL_GPL(snd_soc_register_codec); | |||
4113 | void snd_soc_unregister_codec(struct device *dev) | 4153 | void snd_soc_unregister_codec(struct device *dev) |
4114 | { | 4154 | { |
4115 | struct snd_soc_codec *codec; | 4155 | struct snd_soc_codec *codec; |
4116 | int i; | ||
4117 | 4156 | ||
4118 | list_for_each_entry(codec, &codec_list, list) { | 4157 | list_for_each_entry(codec, &codec_list, list) { |
4119 | if (dev == codec->dev) | 4158 | if (dev == codec->dev) |
@@ -4122,9 +4161,7 @@ void snd_soc_unregister_codec(struct device *dev) | |||
4122 | return; | 4161 | return; |
4123 | 4162 | ||
4124 | found: | 4163 | found: |
4125 | if (codec->num_dai) | 4164 | snd_soc_unregister_dais(dev, codec->num_dai); |
4126 | for (i = 0; i < codec->num_dai; i++) | ||
4127 | snd_soc_unregister_dai(dev); | ||
4128 | 4165 | ||
4129 | mutex_lock(&client_mutex); | 4166 | mutex_lock(&client_mutex); |
4130 | list_del(&codec->list); | 4167 | list_del(&codec->list); |
@@ -4139,6 +4176,92 @@ found: | |||
4139 | } | 4176 | } |
4140 | EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); | 4177 | EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); |
4141 | 4178 | ||
4179 | |||
4180 | /** | ||
4181 | * snd_soc_register_component - Register a component with the ASoC core | ||
4182 | * | ||
4183 | */ | ||
4184 | int snd_soc_register_component(struct device *dev, | ||
4185 | const struct snd_soc_component_driver *cmpnt_drv, | ||
4186 | struct snd_soc_dai_driver *dai_drv, | ||
4187 | int num_dai) | ||
4188 | { | ||
4189 | struct snd_soc_component *cmpnt; | ||
4190 | int ret; | ||
4191 | |||
4192 | dev_dbg(dev, "component register %s\n", dev_name(dev)); | ||
4193 | |||
4194 | cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL); | ||
4195 | if (!cmpnt) { | ||
4196 | dev_err(dev, "ASoC: Failed to allocate memory\n"); | ||
4197 | return -ENOMEM; | ||
4198 | } | ||
4199 | |||
4200 | cmpnt->name = fmt_single_name(dev, &cmpnt->id); | ||
4201 | if (!cmpnt->name) { | ||
4202 | dev_err(dev, "ASoC: Failed to simplifying name\n"); | ||
4203 | return -ENOMEM; | ||
4204 | } | ||
4205 | |||
4206 | cmpnt->dev = dev; | ||
4207 | cmpnt->driver = cmpnt_drv; | ||
4208 | cmpnt->num_dai = num_dai; | ||
4209 | |||
4210 | /* | ||
4211 | * snd_soc_register_dai() uses fmt_single_name(), and | ||
4212 | * snd_soc_register_dais() uses fmt_multiple_name() | ||
4213 | * for dai->name which is used for name based matching | ||
4214 | */ | ||
4215 | if (1 == num_dai) | ||
4216 | ret = snd_soc_register_dai(dev, dai_drv); | ||
4217 | else | ||
4218 | ret = snd_soc_register_dais(dev, dai_drv, num_dai); | ||
4219 | if (ret < 0) { | ||
4220 | dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); | ||
4221 | goto error_component_name; | ||
4222 | } | ||
4223 | |||
4224 | mutex_lock(&client_mutex); | ||
4225 | list_add(&cmpnt->list, &component_list); | ||
4226 | mutex_unlock(&client_mutex); | ||
4227 | |||
4228 | dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name); | ||
4229 | |||
4230 | return ret; | ||
4231 | |||
4232 | error_component_name: | ||
4233 | kfree(cmpnt->name); | ||
4234 | |||
4235 | return ret; | ||
4236 | } | ||
4237 | EXPORT_SYMBOL_GPL(snd_soc_register_component); | ||
4238 | |||
4239 | /** | ||
4240 | * snd_soc_unregister_component - Unregister a component from the ASoC core | ||
4241 | * | ||
4242 | */ | ||
4243 | void snd_soc_unregister_component(struct device *dev) | ||
4244 | { | ||
4245 | struct snd_soc_component *cmpnt; | ||
4246 | |||
4247 | list_for_each_entry(cmpnt, &component_list, list) { | ||
4248 | if (dev == cmpnt->dev) | ||
4249 | goto found; | ||
4250 | } | ||
4251 | return; | ||
4252 | |||
4253 | found: | ||
4254 | snd_soc_unregister_dais(dev, cmpnt->num_dai); | ||
4255 | |||
4256 | mutex_lock(&client_mutex); | ||
4257 | list_del(&cmpnt->list); | ||
4258 | mutex_unlock(&client_mutex); | ||
4259 | |||
4260 | dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); | ||
4261 | kfree(cmpnt->name); | ||
4262 | } | ||
4263 | EXPORT_SYMBOL_GPL(snd_soc_unregister_component); | ||
4264 | |||
4142 | /* Retrieve a card's name from device tree */ | 4265 | /* Retrieve a card's name from device tree */ |
4143 | int snd_soc_of_parse_card_name(struct snd_soc_card *card, | 4266 | int snd_soc_of_parse_card_name(struct snd_soc_card *card, |
4144 | const char *propname) | 4267 | const char *propname) |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d6d9ba2e6916..21779a6a781a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -504,17 +504,27 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, | |||
504 | return 0; | 504 | return 0; |
505 | } | 505 | } |
506 | 506 | ||
507 | /* create new dapm mixer control */ | 507 | /* |
508 | static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | 508 | * Determine if a kcontrol is shared. If it is, look it up. If it isn't, |
509 | * create it. Either way, add the widget into the control's widget list | ||
510 | */ | ||
511 | static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, | ||
512 | int kci, struct snd_soc_dapm_path *path) | ||
509 | { | 513 | { |
510 | struct snd_soc_dapm_context *dapm = w->dapm; | 514 | struct snd_soc_dapm_context *dapm = w->dapm; |
511 | int i, ret = 0; | ||
512 | size_t name_len, prefix_len; | ||
513 | struct snd_soc_dapm_path *path; | ||
514 | struct snd_card *card = dapm->card->snd_card; | 515 | struct snd_card *card = dapm->card->snd_card; |
515 | const char *prefix; | 516 | const char *prefix; |
517 | size_t prefix_len; | ||
518 | int shared; | ||
519 | struct snd_kcontrol *kcontrol; | ||
516 | struct snd_soc_dapm_widget_list *wlist; | 520 | struct snd_soc_dapm_widget_list *wlist; |
521 | int wlistentries; | ||
517 | size_t wlistsize; | 522 | size_t wlistsize; |
523 | bool wname_in_long_name, kcname_in_long_name; | ||
524 | size_t name_len; | ||
525 | char *long_name; | ||
526 | const char *name; | ||
527 | int ret; | ||
518 | 528 | ||
519 | if (dapm->codec) | 529 | if (dapm->codec) |
520 | prefix = dapm->codec->name_prefix; | 530 | prefix = dapm->codec->name_prefix; |
@@ -526,103 +536,141 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
526 | else | 536 | else |
527 | prefix_len = 0; | 537 | prefix_len = 0; |
528 | 538 | ||
529 | /* add kcontrol */ | 539 | shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], |
530 | for (i = 0; i < w->num_kcontrols; i++) { | 540 | &kcontrol); |
531 | 541 | ||
532 | /* match name */ | 542 | if (kcontrol) { |
533 | list_for_each_entry(path, &w->sources, list_sink) { | 543 | wlist = kcontrol->private_data; |
544 | wlistentries = wlist->num_widgets + 1; | ||
545 | } else { | ||
546 | wlist = NULL; | ||
547 | wlistentries = 1; | ||
548 | } | ||
534 | 549 | ||
535 | /* mixer/mux paths name must match control name */ | 550 | wlistsize = sizeof(struct snd_soc_dapm_widget_list) + |
536 | if (path->name != (char *)w->kcontrol_news[i].name) | 551 | wlistentries * sizeof(struct snd_soc_dapm_widget *); |
537 | continue; | 552 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); |
553 | if (wlist == NULL) { | ||
554 | dev_err(dapm->dev, "ASoC: can't allocate widget list for %s\n", | ||
555 | w->name); | ||
556 | return -ENOMEM; | ||
557 | } | ||
558 | wlist->num_widgets = wlistentries; | ||
559 | wlist->widgets[wlistentries - 1] = w; | ||
538 | 560 | ||
539 | if (w->kcontrols[i]) { | 561 | if (!kcontrol) { |
540 | path->kcontrol = w->kcontrols[i]; | 562 | if (shared) { |
541 | continue; | 563 | wname_in_long_name = false; |
564 | kcname_in_long_name = true; | ||
565 | } else { | ||
566 | switch (w->id) { | ||
567 | case snd_soc_dapm_switch: | ||
568 | case snd_soc_dapm_mixer: | ||
569 | wname_in_long_name = true; | ||
570 | kcname_in_long_name = true; | ||
571 | break; | ||
572 | case snd_soc_dapm_mixer_named_ctl: | ||
573 | wname_in_long_name = false; | ||
574 | kcname_in_long_name = true; | ||
575 | break; | ||
576 | case snd_soc_dapm_mux: | ||
577 | case snd_soc_dapm_virt_mux: | ||
578 | case snd_soc_dapm_value_mux: | ||
579 | wname_in_long_name = true; | ||
580 | kcname_in_long_name = false; | ||
581 | break; | ||
582 | default: | ||
583 | kfree(wlist); | ||
584 | return -EINVAL; | ||
542 | } | 585 | } |
586 | } | ||
587 | |||
588 | if (wname_in_long_name && kcname_in_long_name) { | ||
589 | name_len = strlen(w->name) - prefix_len + 1 + | ||
590 | strlen(w->kcontrol_news[kci].name) + 1; | ||
543 | 591 | ||
544 | wlistsize = sizeof(struct snd_soc_dapm_widget_list) + | 592 | long_name = kmalloc(name_len, GFP_KERNEL); |
545 | sizeof(struct snd_soc_dapm_widget *), | 593 | if (long_name == NULL) { |
546 | wlist = kzalloc(wlistsize, GFP_KERNEL); | 594 | kfree(wlist); |
547 | if (wlist == NULL) { | ||
548 | dev_err(dapm->dev, | ||
549 | "ASoC: can't allocate widget list for %s\n", | ||
550 | w->name); | ||
551 | return -ENOMEM; | 595 | return -ENOMEM; |
552 | } | 596 | } |
553 | wlist->num_widgets = 1; | 597 | |
554 | wlist->widgets[0] = w; | 598 | /* |
555 | 599 | * The control will get a prefix from the control | |
556 | /* add dapm control with long name. | 600 | * creation process but we're also using the same |
557 | * for dapm_mixer this is the concatenation of the | 601 | * prefix for widgets so cut the prefix off the |
558 | * mixer and kcontrol name. | 602 | * front of the widget name. |
559 | * for dapm_mixer_named_ctl this is simply the | ||
560 | * kcontrol name. | ||
561 | */ | 603 | */ |
562 | name_len = strlen(w->kcontrol_news[i].name) + 1; | 604 | snprintf(long_name, name_len, "%s %s", |
563 | if (w->id != snd_soc_dapm_mixer_named_ctl) | 605 | w->name + prefix_len, |
564 | name_len += 1 + strlen(w->name); | 606 | w->kcontrol_news[kci].name); |
607 | long_name[name_len - 1] = '\0'; | ||
608 | |||
609 | name = long_name; | ||
610 | } else if (wname_in_long_name) { | ||
611 | long_name = NULL; | ||
612 | name = w->name + prefix_len; | ||
613 | } else { | ||
614 | long_name = NULL; | ||
615 | name = w->kcontrol_news[kci].name; | ||
616 | } | ||
565 | 617 | ||
566 | path->long_name = kmalloc(name_len, GFP_KERNEL); | 618 | kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name, |
619 | prefix); | ||
620 | ret = snd_ctl_add(card, kcontrol); | ||
621 | if (ret < 0) { | ||
622 | dev_err(dapm->dev, | ||
623 | "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", | ||
624 | w->name, name, ret); | ||
625 | kfree(wlist); | ||
626 | kfree(long_name); | ||
627 | return ret; | ||
628 | } | ||
567 | 629 | ||
568 | if (path->long_name == NULL) { | 630 | path->long_name = long_name; |
569 | kfree(wlist); | 631 | } |
570 | return -ENOMEM; | ||
571 | } | ||
572 | 632 | ||
573 | switch (w->id) { | 633 | kcontrol->private_data = wlist; |
574 | default: | 634 | w->kcontrols[kci] = kcontrol; |
575 | /* The control will get a prefix from | 635 | path->kcontrol = kcontrol; |
576 | * the control creation process but | ||
577 | * we're also using the same prefix | ||
578 | * for widgets so cut the prefix off | ||
579 | * the front of the widget name. | ||
580 | */ | ||
581 | snprintf((char *)path->long_name, name_len, | ||
582 | "%s %s", w->name + prefix_len, | ||
583 | w->kcontrol_news[i].name); | ||
584 | break; | ||
585 | case snd_soc_dapm_mixer_named_ctl: | ||
586 | snprintf((char *)path->long_name, name_len, | ||
587 | "%s", w->kcontrol_news[i].name); | ||
588 | break; | ||
589 | } | ||
590 | 636 | ||
591 | ((char *)path->long_name)[name_len - 1] = '\0'; | 637 | return 0; |
638 | } | ||
592 | 639 | ||
593 | path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], | 640 | /* create new dapm mixer control */ |
594 | wlist, path->long_name, | 641 | static int dapm_new_mixer(struct snd_soc_dapm_widget *w) |
595 | prefix); | 642 | { |
596 | ret = snd_ctl_add(card, path->kcontrol); | 643 | int i, ret; |
597 | if (ret < 0) { | 644 | struct snd_soc_dapm_path *path; |
598 | dev_err(dapm->dev, "ASoC: failed to add widget" | 645 | |
599 | " %s dapm kcontrol %s: %d\n", | 646 | /* add kcontrol */ |
600 | w->name, path->long_name, ret); | 647 | for (i = 0; i < w->num_kcontrols; i++) { |
601 | kfree(wlist); | 648 | /* match name */ |
602 | kfree(path->long_name); | 649 | list_for_each_entry(path, &w->sources, list_sink) { |
603 | path->long_name = NULL; | 650 | /* mixer/mux paths name must match control name */ |
604 | return ret; | 651 | if (path->name != (char *)w->kcontrol_news[i].name) |
652 | continue; | ||
653 | |||
654 | if (w->kcontrols[i]) { | ||
655 | path->kcontrol = w->kcontrols[i]; | ||
656 | continue; | ||
605 | } | 657 | } |
606 | w->kcontrols[i] = path->kcontrol; | 658 | |
659 | ret = dapm_create_or_share_mixmux_kcontrol(w, i, path); | ||
660 | if (ret < 0) | ||
661 | return ret; | ||
607 | } | 662 | } |
608 | } | 663 | } |
609 | return ret; | 664 | |
665 | return 0; | ||
610 | } | 666 | } |
611 | 667 | ||
612 | /* create new dapm mux control */ | 668 | /* create new dapm mux control */ |
613 | static int dapm_new_mux(struct snd_soc_dapm_widget *w) | 669 | static int dapm_new_mux(struct snd_soc_dapm_widget *w) |
614 | { | 670 | { |
615 | struct snd_soc_dapm_context *dapm = w->dapm; | 671 | struct snd_soc_dapm_context *dapm = w->dapm; |
616 | struct snd_soc_dapm_path *path = NULL; | 672 | struct snd_soc_dapm_path *path; |
617 | struct snd_kcontrol *kcontrol; | ||
618 | struct snd_card *card = dapm->card->snd_card; | ||
619 | const char *prefix; | ||
620 | size_t prefix_len; | ||
621 | int ret; | 673 | int ret; |
622 | struct snd_soc_dapm_widget_list *wlist; | ||
623 | int shared, wlistentries; | ||
624 | size_t wlistsize; | ||
625 | const char *name; | ||
626 | 674 | ||
627 | if (w->num_kcontrols != 1) { | 675 | if (w->num_kcontrols != 1) { |
628 | dev_err(dapm->dev, | 676 | dev_err(dapm->dev, |
@@ -631,65 +679,19 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
631 | return -EINVAL; | 679 | return -EINVAL; |
632 | } | 680 | } |
633 | 681 | ||
634 | shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0], | 682 | path = list_first_entry(&w->sources, struct snd_soc_dapm_path, |
635 | &kcontrol); | 683 | list_sink); |
636 | if (kcontrol) { | 684 | if (!path) { |
637 | wlist = kcontrol->private_data; | 685 | dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name); |
638 | wlistentries = wlist->num_widgets + 1; | 686 | return -EINVAL; |
639 | } else { | ||
640 | wlist = NULL; | ||
641 | wlistentries = 1; | ||
642 | } | ||
643 | wlistsize = sizeof(struct snd_soc_dapm_widget_list) + | ||
644 | wlistentries * sizeof(struct snd_soc_dapm_widget *), | ||
645 | wlist = krealloc(wlist, wlistsize, GFP_KERNEL); | ||
646 | if (wlist == NULL) { | ||
647 | dev_err(dapm->dev, | ||
648 | "ASoC: can't allocate widget list for %s\n", w->name); | ||
649 | return -ENOMEM; | ||
650 | } | ||
651 | wlist->num_widgets = wlistentries; | ||
652 | wlist->widgets[wlistentries - 1] = w; | ||
653 | |||
654 | if (!kcontrol) { | ||
655 | if (dapm->codec) | ||
656 | prefix = dapm->codec->name_prefix; | ||
657 | else | ||
658 | prefix = NULL; | ||
659 | |||
660 | if (shared) { | ||
661 | name = w->kcontrol_news[0].name; | ||
662 | prefix_len = 0; | ||
663 | } else { | ||
664 | name = w->name; | ||
665 | if (prefix) | ||
666 | prefix_len = strlen(prefix) + 1; | ||
667 | else | ||
668 | prefix_len = 0; | ||
669 | } | ||
670 | |||
671 | /* | ||
672 | * The control will get a prefix from the control creation | ||
673 | * process but we're also using the same prefix for widgets so | ||
674 | * cut the prefix off the front of the widget name. | ||
675 | */ | ||
676 | kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist, | ||
677 | name + prefix_len, prefix); | ||
678 | ret = snd_ctl_add(card, kcontrol); | ||
679 | if (ret < 0) { | ||
680 | dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n", | ||
681 | w->name, ret); | ||
682 | kfree(wlist); | ||
683 | return ret; | ||
684 | } | ||
685 | } | 687 | } |
686 | 688 | ||
687 | kcontrol->private_data = wlist; | 689 | ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path); |
688 | 690 | if (ret < 0) | |
689 | w->kcontrols[0] = kcontrol; | 691 | return ret; |
690 | 692 | ||
691 | list_for_each_entry(path, &w->sources, list_sink) | 693 | list_for_each_entry(path, &w->sources, list_sink) |
692 | path->kcontrol = kcontrol; | 694 | path->kcontrol = w->kcontrols[0]; |
693 | 695 | ||
694 | return 0; | 696 | return 0; |
695 | } | 697 | } |
@@ -705,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) | |||
705 | } | 707 | } |
706 | 708 | ||
707 | /* reset 'walked' bit for each dapm path */ | 709 | /* reset 'walked' bit for each dapm path */ |
708 | static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) | 710 | static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm, |
711 | struct list_head *sink) | ||
709 | { | 712 | { |
710 | struct snd_soc_dapm_path *p; | 713 | struct snd_soc_dapm_path *p; |
711 | 714 | ||
712 | list_for_each_entry(p, &dapm->card->paths, list) | 715 | list_for_each_entry(p, sink, list_source) { |
713 | p->walked = 0; | 716 | if (p->walked) { |
717 | p->walked = 0; | ||
718 | dapm_clear_walk_output(dapm, &p->sink->sinks); | ||
719 | } | ||
720 | } | ||
714 | } | 721 | } |
715 | 722 | ||
723 | static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm, | ||
724 | struct list_head *source) | ||
725 | { | ||
726 | struct snd_soc_dapm_path *p; | ||
727 | |||
728 | list_for_each_entry(p, source, list_sink) { | ||
729 | if (p->walked) { | ||
730 | p->walked = 0; | ||
731 | dapm_clear_walk_input(dapm, &p->source->sources); | ||
732 | } | ||
733 | } | ||
734 | } | ||
735 | |||
736 | |||
716 | /* We implement power down on suspend by checking the power state of | 737 | /* We implement power down on suspend by checking the power state of |
717 | * the ALSA card - when we are suspending the ALSA state for the card | 738 | * the ALSA card - when we are suspending the ALSA state for the card |
718 | * is set to D3. | 739 | * is set to D3. |
@@ -995,13 +1016,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, | |||
995 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 1016 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
996 | dapm_reset(card); | 1017 | dapm_reset(card); |
997 | 1018 | ||
998 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | 1019 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
999 | paths = is_connected_output_ep(dai->playback_widget, list); | 1020 | paths = is_connected_output_ep(dai->playback_widget, list); |
1000 | else | 1021 | dapm_clear_walk_output(&card->dapm, |
1022 | &dai->playback_widget->sinks); | ||
1023 | } else { | ||
1001 | paths = is_connected_input_ep(dai->capture_widget, list); | 1024 | paths = is_connected_input_ep(dai->capture_widget, list); |
1025 | dapm_clear_walk_input(&card->dapm, | ||
1026 | &dai->capture_widget->sources); | ||
1027 | } | ||
1002 | 1028 | ||
1003 | trace_snd_soc_dapm_connected(paths, stream); | 1029 | trace_snd_soc_dapm_connected(paths, stream); |
1004 | dapm_clear_walk(&card->dapm); | ||
1005 | mutex_unlock(&card->dapm_mutex); | 1030 | mutex_unlock(&card->dapm_mutex); |
1006 | 1031 | ||
1007 | return paths; | 1032 | return paths; |
@@ -1104,9 +1129,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) | |||
1104 | DAPM_UPDATE_STAT(w, power_checks); | 1129 | DAPM_UPDATE_STAT(w, power_checks); |
1105 | 1130 | ||
1106 | in = is_connected_input_ep(w, NULL); | 1131 | in = is_connected_input_ep(w, NULL); |
1107 | dapm_clear_walk(w->dapm); | 1132 | dapm_clear_walk_input(w->dapm, &w->sources); |
1108 | out = is_connected_output_ep(w, NULL); | 1133 | out = is_connected_output_ep(w, NULL); |
1109 | dapm_clear_walk(w->dapm); | 1134 | dapm_clear_walk_output(w->dapm, &w->sinks); |
1110 | return out != 0 && in != 0; | 1135 | return out != 0 && in != 0; |
1111 | } | 1136 | } |
1112 | 1137 | ||
@@ -1129,7 +1154,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) | |||
1129 | 1154 | ||
1130 | if (w->active) { | 1155 | if (w->active) { |
1131 | in = is_connected_input_ep(w, NULL); | 1156 | in = is_connected_input_ep(w, NULL); |
1132 | dapm_clear_walk(w->dapm); | 1157 | dapm_clear_walk_input(w->dapm, &w->sources); |
1133 | return in != 0; | 1158 | return in != 0; |
1134 | } else { | 1159 | } else { |
1135 | return dapm_generic_check_power(w); | 1160 | return dapm_generic_check_power(w); |
@@ -1145,7 +1170,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) | |||
1145 | 1170 | ||
1146 | if (w->active) { | 1171 | if (w->active) { |
1147 | out = is_connected_output_ep(w, NULL); | 1172 | out = is_connected_output_ep(w, NULL); |
1148 | dapm_clear_walk(w->dapm); | 1173 | dapm_clear_walk_output(w->dapm, &w->sinks); |
1149 | return out != 0; | 1174 | return out != 0; |
1150 | } else { | 1175 | } else { |
1151 | return dapm_generic_check_power(w); | 1176 | return dapm_generic_check_power(w); |
@@ -1177,8 +1202,6 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) | |||
1177 | return 1; | 1202 | return 1; |
1178 | } | 1203 | } |
1179 | 1204 | ||
1180 | dapm_clear_walk(w->dapm); | ||
1181 | |||
1182 | return 0; | 1205 | return 0; |
1183 | } | 1206 | } |
1184 | 1207 | ||
@@ -1759,9 +1782,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, | |||
1759 | return -ENOMEM; | 1782 | return -ENOMEM; |
1760 | 1783 | ||
1761 | in = is_connected_input_ep(w, NULL); | 1784 | in = is_connected_input_ep(w, NULL); |
1762 | dapm_clear_walk(w->dapm); | 1785 | dapm_clear_walk_input(w->dapm, &w->sources); |
1763 | out = is_connected_output_ep(w, NULL); | 1786 | out = is_connected_output_ep(w, NULL); |
1764 | dapm_clear_walk(w->dapm); | 1787 | dapm_clear_walk_output(w->dapm, &w->sinks); |
1765 | 1788 | ||
1766 | ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", | 1789 | ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", |
1767 | w->name, w->power ? "On" : "Off", | 1790 | w->name, w->power ? "On" : "Off", |
@@ -3137,7 +3160,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
3137 | break; | 3160 | break; |
3138 | } | 3161 | } |
3139 | 3162 | ||
3140 | dapm->n_widgets++; | ||
3141 | w->dapm = dapm; | 3163 | w->dapm = dapm; |
3142 | w->codec = dapm->codec; | 3164 | w->codec = dapm->codec; |
3143 | w->platform = dapm->platform; | 3165 | w->platform = dapm->platform; |
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 111b7d921e89..aa924d9b7986 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c | |||
@@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data { | |||
33 | dma_cookie_t cookie; | 33 | dma_cookie_t cookie; |
34 | 34 | ||
35 | unsigned int pos; | 35 | unsigned int pos; |
36 | |||
37 | void *data; | ||
38 | }; | 36 | }; |
39 | 37 | ||
40 | static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( | 38 | static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( |
@@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( | |||
43 | return substream->runtime->private_data; | 41 | return substream->runtime->private_data; |
44 | } | 42 | } |
45 | 43 | ||
46 | /** | ||
47 | * snd_dmaengine_pcm_set_data - Set dmaengine substream private data | ||
48 | * @substream: PCM substream | ||
49 | * @data: Data to set | ||
50 | */ | ||
51 | void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data) | ||
52 | { | ||
53 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
54 | |||
55 | prtd->data = data; | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data); | ||
58 | |||
59 | /** | ||
60 | * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data | ||
61 | * @substream: PCM substream | ||
62 | * | ||
63 | * Returns the data previously set with snd_dmaengine_pcm_set_data | ||
64 | */ | ||
65 | void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream) | ||
66 | { | ||
67 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
68 | |||
69 | return prtd->data; | ||
70 | } | ||
71 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data); | ||
72 | |||
73 | struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) | 44 | struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) |
74 | { | 45 | { |
75 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | 46 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); |
@@ -118,10 +89,49 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, | |||
118 | slave_config->src_addr_width = buswidth; | 89 | slave_config->src_addr_width = buswidth; |
119 | } | 90 | } |
120 | 91 | ||
92 | slave_config->device_fc = false; | ||
93 | |||
121 | return 0; | 94 | return 0; |
122 | } | 95 | } |
123 | EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); | 96 | EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); |
124 | 97 | ||
98 | /** | ||
99 | * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config | ||
100 | * using DAI DMA data. | ||
101 | * @substream: PCM substream | ||
102 | * @dma_data: DAI DMA data | ||
103 | * @slave_config: DMA slave configuration | ||
104 | * | ||
105 | * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and | ||
106 | * slave_id fields of the DMA slave config from the same fields of the DAI DMA | ||
107 | * data struct. The src and dst fields will be initialized depending on the | ||
108 | * direction of the substream. If the substream is a playback stream the dst | ||
109 | * fields will be initialized, if it is a capture stream the src fields will be | ||
110 | * initialized. The {dst,src}_addr_width field will only be initialized if the | ||
111 | * addr_width field of the DAI DMA data struct is not equal to | ||
112 | * DMA_SLAVE_BUSWIDTH_UNDEFINED. | ||
113 | */ | ||
114 | void snd_dmaengine_pcm_set_config_from_dai_data( | ||
115 | const struct snd_pcm_substream *substream, | ||
116 | const struct snd_dmaengine_dai_dma_data *dma_data, | ||
117 | struct dma_slave_config *slave_config) | ||
118 | { | ||
119 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
120 | slave_config->dst_addr = dma_data->addr; | ||
121 | slave_config->dst_maxburst = dma_data->maxburst; | ||
122 | if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) | ||
123 | slave_config->dst_addr_width = dma_data->addr_width; | ||
124 | } else { | ||
125 | slave_config->src_addr = dma_data->addr; | ||
126 | slave_config->src_maxburst = dma_data->maxburst; | ||
127 | if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) | ||
128 | slave_config->src_addr_width = dma_data->addr_width; | ||
129 | } | ||
130 | |||
131 | slave_config->slave_id = dma_data->slave_id; | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); | ||
134 | |||
125 | static void dmaengine_pcm_dma_complete(void *arg) | 135 | static void dmaengine_pcm_dma_complete(void *arg) |
126 | { | 136 | { |
127 | struct snd_pcm_substream *substream = arg; | 137 | struct snd_pcm_substream *substream = arg; |
@@ -244,44 +254,48 @@ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) | |||
244 | } | 254 | } |
245 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); | 255 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); |
246 | 256 | ||
247 | static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, | 257 | /** |
248 | dma_filter_fn filter_fn, void *filter_data) | 258 | * snd_dmaengine_pcm_request_channel - Request channel for the dmaengine PCM |
259 | * @filter_fn: Filter function used to request the DMA channel | ||
260 | * @filter_data: Data passed to the DMA filter function | ||
261 | * | ||
262 | * Returns NULL or the requested DMA channel. | ||
263 | * | ||
264 | * This function request a DMA channel for usage with dmaengine PCM. | ||
265 | */ | ||
266 | struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn, | ||
267 | void *filter_data) | ||
249 | { | 268 | { |
250 | dma_cap_mask_t mask; | 269 | dma_cap_mask_t mask; |
251 | 270 | ||
252 | dma_cap_zero(mask); | 271 | dma_cap_zero(mask); |
253 | dma_cap_set(DMA_SLAVE, mask); | 272 | dma_cap_set(DMA_SLAVE, mask); |
254 | dma_cap_set(DMA_CYCLIC, mask); | 273 | dma_cap_set(DMA_CYCLIC, mask); |
255 | prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data); | ||
256 | 274 | ||
257 | if (!prtd->dma_chan) | 275 | return dma_request_channel(mask, filter_fn, filter_data); |
258 | return -ENXIO; | ||
259 | |||
260 | return 0; | ||
261 | } | 276 | } |
277 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_channel); | ||
262 | 278 | ||
263 | /** | 279 | /** |
264 | * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream | 280 | * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream |
265 | * @substream: PCM substream | 281 | * @substream: PCM substream |
266 | * @filter_fn: Filter function used to request the DMA channel | 282 | * @chan: DMA channel to use for data transfers |
267 | * @filter_data: Data passed to the DMA filter function | ||
268 | * | 283 | * |
269 | * Returns 0 on success, a negative error code otherwise. | 284 | * Returns 0 on success, a negative error code otherwise. |
270 | * | 285 | * |
271 | * This function will request a DMA channel using the passed filter function and | 286 | * The function should usually be called from the pcm open callback. Note that |
272 | * data. The function should usually be called from the pcm open callback. | 287 | * this function will use private_data field of the substream's runtime. So it |
273 | * | 288 | * is not availabe to your pcm driver implementation. |
274 | * Note that this function will use private_data field of the substream's | ||
275 | * runtime. So it is not availabe to your pcm driver implementation. If you need | ||
276 | * to keep additional data attached to a substream use | ||
277 | * snd_dmaengine_pcm_{set,get}_data. | ||
278 | */ | 289 | */ |
279 | int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, | 290 | int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, |
280 | dma_filter_fn filter_fn, void *filter_data) | 291 | struct dma_chan *chan) |
281 | { | 292 | { |
282 | struct dmaengine_pcm_runtime_data *prtd; | 293 | struct dmaengine_pcm_runtime_data *prtd; |
283 | int ret; | 294 | int ret; |
284 | 295 | ||
296 | if (!chan) | ||
297 | return -ENXIO; | ||
298 | |||
285 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 299 | ret = snd_pcm_hw_constraint_integer(substream->runtime, |
286 | SNDRV_PCM_HW_PARAM_PERIODS); | 300 | SNDRV_PCM_HW_PARAM_PERIODS); |
287 | if (ret < 0) | 301 | if (ret < 0) |
@@ -291,11 +305,7 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, | |||
291 | if (!prtd) | 305 | if (!prtd) |
292 | return -ENOMEM; | 306 | return -ENOMEM; |
293 | 307 | ||
294 | ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data); | 308 | prtd->dma_chan = chan; |
295 | if (ret < 0) { | ||
296 | kfree(prtd); | ||
297 | return ret; | ||
298 | } | ||
299 | 309 | ||
300 | substream->runtime->private_data = prtd; | 310 | substream->runtime->private_data = prtd; |
301 | 311 | ||
@@ -304,6 +314,27 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, | |||
304 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); | 314 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); |
305 | 315 | ||
306 | /** | 316 | /** |
317 | * snd_dmaengine_pcm_open_request_chan - Open a dmaengine based PCM substream and request channel | ||
318 | * @substream: PCM substream | ||
319 | * @filter_fn: Filter function used to request the DMA channel | ||
320 | * @filter_data: Data passed to the DMA filter function | ||
321 | * | ||
322 | * Returns 0 on success, a negative error code otherwise. | ||
323 | * | ||
324 | * This function will request a DMA channel using the passed filter function and | ||
325 | * data. The function should usually be called from the pcm open callback. Note | ||
326 | * that this function will use private_data field of the substream's runtime. So | ||
327 | * it is not availabe to your pcm driver implementation. | ||
328 | */ | ||
329 | int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, | ||
330 | dma_filter_fn filter_fn, void *filter_data) | ||
331 | { | ||
332 | return snd_dmaengine_pcm_open(substream, | ||
333 | snd_dmaengine_pcm_request_channel(filter_fn, filter_data)); | ||
334 | } | ||
335 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan); | ||
336 | |||
337 | /** | ||
307 | * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream | 338 | * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream |
308 | * @substream: PCM substream | 339 | * @substream: PCM substream |
309 | */ | 340 | */ |
@@ -311,11 +342,26 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) | |||
311 | { | 342 | { |
312 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | 343 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); |
313 | 344 | ||
314 | dma_release_channel(prtd->dma_chan); | ||
315 | kfree(prtd); | 345 | kfree(prtd); |
316 | 346 | ||
317 | return 0; | 347 | return 0; |
318 | } | 348 | } |
319 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); | 349 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); |
320 | 350 | ||
351 | /** | ||
352 | * snd_dmaengine_pcm_release_chan_close - Close a dmaengine based PCM substream and release channel | ||
353 | * @substream: PCM substream | ||
354 | * | ||
355 | * Releases the DMA channel associated with the PCM substream. | ||
356 | */ | ||
357 | int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) | ||
358 | { | ||
359 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
360 | |||
361 | dma_release_channel(prtd->dma_chan); | ||
362 | |||
363 | return snd_dmaengine_pcm_close(substream); | ||
364 | } | ||
365 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); | ||
366 | |||
321 | MODULE_LICENSE("GPL"); | 367 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c new file mode 100644 index 000000000000..e29ec3cd84b1 --- /dev/null +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013, Analog Devices Inc. | ||
3 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License along | ||
11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/dmaengine.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <sound/pcm.h> | ||
20 | #include <sound/pcm_params.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/of.h> | ||
24 | |||
25 | #include <sound/dmaengine_pcm.h> | ||
26 | |||
27 | struct dmaengine_pcm { | ||
28 | struct dma_chan *chan[SNDRV_PCM_STREAM_CAPTURE + 1]; | ||
29 | const struct snd_dmaengine_pcm_config *config; | ||
30 | struct snd_soc_platform platform; | ||
31 | unsigned int flags; | ||
32 | }; | ||
33 | |||
34 | static struct dmaengine_pcm *soc_platform_to_pcm(struct snd_soc_platform *p) | ||
35 | { | ||
36 | return container_of(p, struct dmaengine_pcm, platform); | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * snd_dmaengine_pcm_prepare_slave_config() - Generic prepare_slave_config callback | ||
41 | * @substream: PCM substream | ||
42 | * @params: hw_params | ||
43 | * @slave_config: DMA slave config to prepare | ||
44 | * | ||
45 | * This function can be used as a generic prepare_slave_config callback for | ||
46 | * platforms which make use of the snd_dmaengine_dai_dma_data struct for their | ||
47 | * DAI DMA data. Internally the function will first call | ||
48 | * snd_hwparams_to_dma_slave_config to fill in the slave config based on the | ||
49 | * hw_params, followed by snd_dmaengine_set_config_from_dai_data to fill in the | ||
50 | * remaining fields based on the DAI DMA data. | ||
51 | */ | ||
52 | int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream, | ||
53 | struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config) | ||
54 | { | ||
55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
56 | struct snd_dmaengine_dai_dma_data *dma_data; | ||
57 | int ret; | ||
58 | |||
59 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
60 | |||
61 | ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); | ||
62 | if (ret) | ||
63 | return ret; | ||
64 | |||
65 | snd_dmaengine_pcm_set_config_from_dai_data(substream, dma_data, | ||
66 | slave_config); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_prepare_slave_config); | ||
71 | |||
72 | static int dmaengine_pcm_hw_params(struct snd_pcm_substream *substream, | ||
73 | struct snd_pcm_hw_params *params) | ||
74 | { | ||
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
76 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | ||
77 | struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); | ||
78 | struct dma_slave_config slave_config; | ||
79 | int ret; | ||
80 | |||
81 | if (pcm->config->prepare_slave_config) { | ||
82 | ret = pcm->config->prepare_slave_config(substream, params, | ||
83 | &slave_config); | ||
84 | if (ret) | ||
85 | return ret; | ||
86 | |||
87 | ret = dmaengine_slave_config(chan, &slave_config); | ||
88 | if (ret) | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | ||
93 | } | ||
94 | |||
95 | static int dmaengine_pcm_open(struct snd_pcm_substream *substream) | ||
96 | { | ||
97 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
98 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | ||
99 | struct dma_chan *chan = pcm->chan[substream->stream]; | ||
100 | int ret; | ||
101 | |||
102 | ret = snd_soc_set_runtime_hwparams(substream, | ||
103 | pcm->config->pcm_hardware); | ||
104 | if (ret) | ||
105 | return ret; | ||
106 | |||
107 | return snd_dmaengine_pcm_open(substream, chan); | ||
108 | } | ||
109 | |||
110 | static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm, | ||
111 | struct snd_pcm_substream *substream) | ||
112 | { | ||
113 | if (!pcm->chan[substream->stream]) | ||
114 | return NULL; | ||
115 | |||
116 | return pcm->chan[substream->stream]->device->dev; | ||
117 | } | ||
118 | |||
119 | static void dmaengine_pcm_free(struct snd_pcm *pcm) | ||
120 | { | ||
121 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
122 | } | ||
123 | |||
124 | static struct dma_chan *dmaengine_pcm_compat_request_channel( | ||
125 | struct snd_soc_pcm_runtime *rtd, | ||
126 | struct snd_pcm_substream *substream) | ||
127 | { | ||
128 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | ||
129 | |||
130 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) | ||
131 | return pcm->chan[0]; | ||
132 | |||
133 | if (pcm->config->compat_request_channel) | ||
134 | return pcm->config->compat_request_channel(rtd, substream); | ||
135 | |||
136 | return snd_dmaengine_pcm_request_channel(pcm->config->compat_filter_fn, | ||
137 | snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); | ||
138 | } | ||
139 | |||
140 | static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
141 | { | ||
142 | struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); | ||
143 | const struct snd_dmaengine_pcm_config *config = pcm->config; | ||
144 | struct snd_pcm_substream *substream; | ||
145 | unsigned int i; | ||
146 | int ret; | ||
147 | |||
148 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
149 | substream = rtd->pcm->streams[i].substream; | ||
150 | if (!substream) | ||
151 | continue; | ||
152 | |||
153 | if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) { | ||
154 | pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd, | ||
155 | substream); | ||
156 | } | ||
157 | |||
158 | if (!pcm->chan[i]) { | ||
159 | dev_err(rtd->platform->dev, | ||
160 | "Missing dma channel for stream: %d\n", i); | ||
161 | ret = -EINVAL; | ||
162 | goto err_free; | ||
163 | } | ||
164 | |||
165 | ret = snd_pcm_lib_preallocate_pages(substream, | ||
166 | SNDRV_DMA_TYPE_DEV, | ||
167 | dmaengine_dma_dev(pcm, substream), | ||
168 | config->prealloc_buffer_size, | ||
169 | config->pcm_hardware->buffer_bytes_max); | ||
170 | if (ret) | ||
171 | goto err_free; | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | |||
176 | err_free: | ||
177 | dmaengine_pcm_free(rtd->pcm); | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static const struct snd_pcm_ops dmaengine_pcm_ops = { | ||
182 | .open = dmaengine_pcm_open, | ||
183 | .close = snd_dmaengine_pcm_close, | ||
184 | .ioctl = snd_pcm_lib_ioctl, | ||
185 | .hw_params = dmaengine_pcm_hw_params, | ||
186 | .hw_free = snd_pcm_lib_free_pages, | ||
187 | .trigger = snd_dmaengine_pcm_trigger, | ||
188 | .pointer = snd_dmaengine_pcm_pointer, | ||
189 | }; | ||
190 | |||
191 | static const struct snd_soc_platform_driver dmaengine_pcm_platform = { | ||
192 | .ops = &dmaengine_pcm_ops, | ||
193 | .pcm_new = dmaengine_pcm_new, | ||
194 | .pcm_free = dmaengine_pcm_free, | ||
195 | .probe_order = SND_SOC_COMP_ORDER_LATE, | ||
196 | }; | ||
197 | |||
198 | static const struct snd_pcm_ops dmaengine_no_residue_pcm_ops = { | ||
199 | .open = dmaengine_pcm_open, | ||
200 | .close = snd_dmaengine_pcm_close, | ||
201 | .ioctl = snd_pcm_lib_ioctl, | ||
202 | .hw_params = dmaengine_pcm_hw_params, | ||
203 | .hw_free = snd_pcm_lib_free_pages, | ||
204 | .trigger = snd_dmaengine_pcm_trigger, | ||
205 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
206 | }; | ||
207 | |||
208 | static const struct snd_soc_platform_driver dmaengine_no_residue_pcm_platform = { | ||
209 | .ops = &dmaengine_no_residue_pcm_ops, | ||
210 | .pcm_new = dmaengine_pcm_new, | ||
211 | .pcm_free = dmaengine_pcm_free, | ||
212 | .probe_order = SND_SOC_COMP_ORDER_LATE, | ||
213 | }; | ||
214 | |||
215 | static const char * const dmaengine_pcm_dma_channel_names[] = { | ||
216 | [SNDRV_PCM_STREAM_PLAYBACK] = "tx", | ||
217 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", | ||
218 | }; | ||
219 | |||
220 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | ||
221 | struct device *dev) | ||
222 | { | ||
223 | unsigned int i; | ||
224 | |||
225 | if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_DT) || !dev->of_node) | ||
226 | return; | ||
227 | |||
228 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) { | ||
229 | pcm->chan[0] = dma_request_slave_channel(dev, "rx-tx"); | ||
230 | pcm->chan[1] = pcm->chan[0]; | ||
231 | } else { | ||
232 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
233 | pcm->chan[i] = dma_request_slave_channel(dev, | ||
234 | dmaengine_pcm_dma_channel_names[i]); | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * snd_dmaengine_pcm_register - Register a dmaengine based PCM device | ||
241 | * @dev: The parent device for the PCM device | ||
242 | * @config: Platform specific PCM configuration | ||
243 | * @flags: Platform specific quirks | ||
244 | */ | ||
245 | int snd_dmaengine_pcm_register(struct device *dev, | ||
246 | const struct snd_dmaengine_pcm_config *config, unsigned int flags) | ||
247 | { | ||
248 | struct dmaengine_pcm *pcm; | ||
249 | |||
250 | pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); | ||
251 | if (!pcm) | ||
252 | return -ENOMEM; | ||
253 | |||
254 | pcm->config = config; | ||
255 | pcm->flags = flags; | ||
256 | |||
257 | dmaengine_pcm_request_chan_of(pcm, dev); | ||
258 | |||
259 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) | ||
260 | return snd_soc_add_platform(dev, &pcm->platform, | ||
261 | &dmaengine_no_residue_pcm_platform); | ||
262 | else | ||
263 | return snd_soc_add_platform(dev, &pcm->platform, | ||
264 | &dmaengine_pcm_platform); | ||
265 | } | ||
266 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register); | ||
267 | |||
268 | /** | ||
269 | * snd_dmaengine_pcm_unregister - Removes a dmaengine based PCM device | ||
270 | * @dev: Parent device the PCM was register with | ||
271 | * | ||
272 | * Removes a dmaengine based PCM device previously registered with | ||
273 | * snd_dmaengine_pcm_register. | ||
274 | */ | ||
275 | void snd_dmaengine_pcm_unregister(struct device *dev) | ||
276 | { | ||
277 | struct snd_soc_platform *platform; | ||
278 | struct dmaengine_pcm *pcm; | ||
279 | unsigned int i; | ||
280 | |||
281 | platform = snd_soc_lookup_platform(dev); | ||
282 | if (!platform) | ||
283 | return; | ||
284 | |||
285 | pcm = soc_platform_to_pcm(platform); | ||
286 | |||
287 | for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { | ||
288 | if (pcm->chan[i]) { | ||
289 | dma_release_channel(pcm->chan[i]); | ||
290 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | snd_soc_remove_platform(platform); | ||
296 | kfree(pcm); | ||
297 | } | ||
298 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister); | ||
299 | |||
300 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 29183ef2b93d..8ca9ecc5ac57 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -158,10 +158,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
158 | return -EINVAL; | 158 | return -EINVAL; |
159 | } | 159 | } |
160 | 160 | ||
161 | if (IS_ERR(codec->control_data)) | 161 | return PTR_RET(codec->control_data); |
162 | return PTR_ERR(codec->control_data); | ||
163 | |||
164 | return 0; | ||
165 | } | 162 | } |
166 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); | 163 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); |
167 | #else | 164 | #else |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index fe4541df498c..4b3be6c3c91e 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -90,8 +90,33 @@ static struct snd_soc_platform_driver dummy_platform = { | |||
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct snd_soc_codec_driver dummy_codec; | 92 | static struct snd_soc_codec_driver dummy_codec; |
93 | |||
94 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 | ||
95 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ | ||
96 | SNDRV_PCM_FMTBIT_U8 | \ | ||
97 | SNDRV_PCM_FMTBIT_S16_LE | \ | ||
98 | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
99 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
100 | SNDRV_PCM_FMTBIT_U24_LE | \ | ||
101 | SNDRV_PCM_FMTBIT_S32_LE | \ | ||
102 | SNDRV_PCM_FMTBIT_U32_LE | \ | ||
103 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) | ||
93 | static struct snd_soc_dai_driver dummy_dai = { | 104 | static struct snd_soc_dai_driver dummy_dai = { |
94 | .name = "snd-soc-dummy-dai", | 105 | .name = "snd-soc-dummy-dai", |
106 | .playback = { | ||
107 | .stream_name = "Playback", | ||
108 | .channels_min = 1, | ||
109 | .channels_max = 384, | ||
110 | .rates = STUB_RATES, | ||
111 | .formats = STUB_FORMATS, | ||
112 | }, | ||
113 | .capture = { | ||
114 | .stream_name = "Capture", | ||
115 | .channels_min = 1, | ||
116 | .channels_max = 384, | ||
117 | .rates = STUB_RATES, | ||
118 | .formats = STUB_FORMATS, | ||
119 | }, | ||
95 | }; | 120 | }; |
96 | 121 | ||
97 | static int snd_soc_dummy_probe(struct platform_device *pdev) | 122 | static int snd_soc_dummy_probe(struct platform_device *pdev) |
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index c7c4b20395bb..14d57e89bcba 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c | |||
@@ -170,6 +170,10 @@ struct snd_soc_dai_driver spdif_in_dai = { | |||
170 | .ops = &spdif_in_dai_ops, | 170 | .ops = &spdif_in_dai_ops, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static const struct snd_soc_component_driver spdif_in_component = { | ||
174 | .name = "spdif-in", | ||
175 | }; | ||
176 | |||
173 | static irqreturn_t spdif_in_irq(int irq, void *arg) | 177 | static irqreturn_t spdif_in_irq(int irq, void *arg) |
174 | { | 178 | { |
175 | struct spdif_in_dev *host = (struct spdif_in_dev *)arg; | 179 | struct spdif_in_dev *host = (struct spdif_in_dev *)arg; |
@@ -258,7 +262,8 @@ static int spdif_in_probe(struct platform_device *pdev) | |||
258 | return ret; | 262 | return ret; |
259 | } | 263 | } |
260 | 264 | ||
261 | ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai); | 265 | ret = snd_soc_register_component(&pdev->dev, &spdif_in_component, |
266 | &spdif_in_dai, 1); | ||
262 | if (ret != 0) { | 267 | if (ret != 0) { |
263 | clk_put(host->clk); | 268 | clk_put(host->clk); |
264 | return ret; | 269 | return ret; |
@@ -271,7 +276,7 @@ static int spdif_in_remove(struct platform_device *pdev) | |||
271 | { | 276 | { |
272 | struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev); | 277 | struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev); |
273 | 278 | ||
274 | snd_soc_unregister_dai(&pdev->dev); | 279 | snd_soc_unregister_component(&pdev->dev); |
275 | dev_set_drvdata(&pdev->dev, NULL); | 280 | dev_set_drvdata(&pdev->dev, NULL); |
276 | 281 | ||
277 | clk_put(host->clk); | 282 | clk_put(host->clk); |
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 5eac4cda2fd7..1e3c3dda3598 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c | |||
@@ -270,6 +270,10 @@ static struct snd_soc_dai_driver spdif_out_dai = { | |||
270 | .ops = &spdif_out_dai_ops, | 270 | .ops = &spdif_out_dai_ops, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static const struct snd_soc_component_driver spdif_out_component = { | ||
274 | .name = "spdif-out", | ||
275 | }; | ||
276 | |||
273 | static int spdif_out_probe(struct platform_device *pdev) | 277 | static int spdif_out_probe(struct platform_device *pdev) |
274 | { | 278 | { |
275 | struct spdif_out_dev *host; | 279 | struct spdif_out_dev *host; |
@@ -314,7 +318,8 @@ static int spdif_out_probe(struct platform_device *pdev) | |||
314 | 318 | ||
315 | dev_set_drvdata(&pdev->dev, host); | 319 | dev_set_drvdata(&pdev->dev, host); |
316 | 320 | ||
317 | ret = snd_soc_register_dai(&pdev->dev, &spdif_out_dai); | 321 | ret = snd_soc_register_component(&pdev->dev, &spdif_out_component, |
322 | &spdif_out_dai, 1); | ||
318 | if (ret != 0) { | 323 | if (ret != 0) { |
319 | clk_put(host->clk); | 324 | clk_put(host->clk); |
320 | return ret; | 325 | return ret; |
@@ -327,7 +332,7 @@ static int spdif_out_remove(struct platform_device *pdev) | |||
327 | { | 332 | { |
328 | struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev); | 333 | struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev); |
329 | 334 | ||
330 | snd_soc_unregister_dai(&pdev->dev); | 335 | snd_soc_unregister_component(&pdev->dev); |
331 | dev_set_drvdata(&pdev->dev, NULL); | 336 | dev_set_drvdata(&pdev->dev, NULL); |
332 | 337 | ||
333 | clk_put(host->clk); | 338 | clk_put(host->clk); |
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 5e7aebe1e664..2fbd4899d8ef 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
26 | #include <sound/spear_dma.h> | 26 | #include <sound/spear_dma.h> |
27 | 27 | ||
28 | struct snd_pcm_hardware spear_pcm_hardware = { | 28 | static struct snd_pcm_hardware spear_pcm_hardware = { |
29 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 29 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
30 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | | 30 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | |
31 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 31 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), |
@@ -64,21 +64,8 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) | |||
64 | if (ret) | 64 | if (ret) |
65 | return ret; | 65 | return ret; |
66 | 66 | ||
67 | ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); | 67 | return snd_dmaengine_pcm_open_request_chan(substream, dma_data->filter, |
68 | if (ret) | 68 | dma_data); |
69 | return ret; | ||
70 | |||
71 | snd_dmaengine_pcm_set_data(substream, dma_data); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int spear_pcm_close(struct snd_pcm_substream *substream) | ||
77 | { | ||
78 | |||
79 | snd_dmaengine_pcm_close(substream); | ||
80 | |||
81 | return 0; | ||
82 | } | 69 | } |
83 | 70 | ||
84 | static int spear_pcm_mmap(struct snd_pcm_substream *substream, | 71 | static int spear_pcm_mmap(struct snd_pcm_substream *substream, |
@@ -93,7 +80,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream, | |||
93 | 80 | ||
94 | static struct snd_pcm_ops spear_pcm_ops = { | 81 | static struct snd_pcm_ops spear_pcm_ops = { |
95 | .open = spear_pcm_open, | 82 | .open = spear_pcm_open, |
96 | .close = spear_pcm_close, | 83 | .close = snd_dmaengine_pcm_close_release_chan, |
97 | .ioctl = snd_pcm_lib_ioctl, | 84 | .ioctl = snd_pcm_lib_ioctl, |
98 | .hw_params = spear_pcm_hw_params, | 85 | .hw_params = spear_pcm_hw_params, |
99 | .hw_free = spear_pcm_hw_free, | 86 | .hw_free = spear_pcm_hw_free, |
@@ -178,7 +165,7 @@ static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
178 | return 0; | 165 | return 0; |
179 | } | 166 | } |
180 | 167 | ||
181 | struct snd_soc_platform_driver spear_soc_platform = { | 168 | static struct snd_soc_platform_driver spear_soc_platform = { |
182 | .ops = &spear_pcm_ops, | 169 | .ops = &spear_pcm_ops, |
183 | .pcm_new = spear_pcm_new, | 170 | .pcm_new = spear_pcm_new, |
184 | .pcm_free = spear_pcm_free, | 171 | .pcm_free = spear_pcm_free, |
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index dbc27ce1d4de..b1c9d573da05 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig | |||
@@ -2,7 +2,7 @@ config SND_SOC_TEGRA | |||
2 | tristate "SoC Audio for the Tegra System-on-Chip" | 2 | tristate "SoC Audio for the Tegra System-on-Chip" |
3 | depends on ARCH_TEGRA && TEGRA20_APB_DMA | 3 | depends on ARCH_TEGRA && TEGRA20_APB_DMA |
4 | select REGMAP_MMIO | 4 | select REGMAP_MMIO |
5 | select SND_SOC_DMAENGINE_PCM if TEGRA20_APB_DMA | 5 | select SND_SOC_GENERIC_DMAENGINE_PCM if TEGRA20_APB_DMA |
6 | help | 6 | help |
7 | Say Y or M here if you want support for SoC audio on Tegra. | 7 | Say Y or M here if you want support for SoC audio on Tegra. |
8 | 8 | ||
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 336dcdd3e8a4..2f70ea7f6618 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <sound/pcm.h> | 35 | #include <sound/pcm.h> |
36 | #include <sound/pcm_params.h> | 36 | #include <sound/pcm_params.h> |
37 | #include <sound/soc.h> | 37 | #include <sound/soc.h> |
38 | #include <sound/dmaengine_pcm.h> | ||
38 | 39 | ||
39 | #include "tegra_asoc_utils.h" | 40 | #include "tegra_asoc_utils.h" |
40 | #include "tegra20_ac97.h" | 41 | #include "tegra20_ac97.h" |
@@ -248,6 +249,10 @@ static struct snd_soc_dai_driver tegra20_ac97_dai = { | |||
248 | .ops = &tegra20_ac97_dai_ops, | 249 | .ops = &tegra20_ac97_dai_ops, |
249 | }; | 250 | }; |
250 | 251 | ||
252 | static const struct snd_soc_component_driver tegra20_ac97_component = { | ||
253 | .name = DRV_NAME, | ||
254 | }; | ||
255 | |||
251 | static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg) | 256 | static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg) |
252 | { | 257 | { |
253 | switch (reg) { | 258 | switch (reg) { |
@@ -389,16 +394,17 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) | |||
389 | } | 394 | } |
390 | 395 | ||
391 | ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; | 396 | ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; |
392 | ac97->capture_dma_data.wrap = 4; | 397 | ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
393 | ac97->capture_dma_data.width = 32; | 398 | ac97->capture_dma_data.maxburst = 4; |
394 | ac97->capture_dma_data.req_sel = of_dma[1]; | 399 | ac97->capture_dma_data.slave_id = of_dma[1]; |
395 | 400 | ||
396 | ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; | 401 | ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; |
397 | ac97->playback_dma_data.wrap = 4; | 402 | ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
398 | ac97->playback_dma_data.width = 32; | 403 | ac97->capture_dma_data.maxburst = 4; |
399 | ac97->playback_dma_data.req_sel = of_dma[1]; | 404 | ac97->capture_dma_data.slave_id = of_dma[0]; |
400 | 405 | ||
401 | ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1); | 406 | ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, |
407 | &tegra20_ac97_dai, 1); | ||
402 | if (ret) { | 408 | if (ret) { |
403 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | 409 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); |
404 | ret = -ENOMEM; | 410 | ret = -ENOMEM; |
@@ -408,7 +414,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) | |||
408 | ret = tegra_pcm_platform_register(&pdev->dev); | 414 | ret = tegra_pcm_platform_register(&pdev->dev); |
409 | if (ret) { | 415 | if (ret) { |
410 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | 416 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); |
411 | goto err_unregister_dai; | 417 | goto err_unregister_component; |
412 | } | 418 | } |
413 | 419 | ||
414 | ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); | 420 | ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); |
@@ -434,8 +440,8 @@ err_asoc_utils_fini: | |||
434 | tegra_asoc_utils_fini(&ac97->util_data); | 440 | tegra_asoc_utils_fini(&ac97->util_data); |
435 | err_unregister_pcm: | 441 | err_unregister_pcm: |
436 | tegra_pcm_platform_unregister(&pdev->dev); | 442 | tegra_pcm_platform_unregister(&pdev->dev); |
437 | err_unregister_dai: | 443 | err_unregister_component: |
438 | snd_soc_unregister_dai(&pdev->dev); | 444 | snd_soc_unregister_component(&pdev->dev); |
439 | err_clk_put: | 445 | err_clk_put: |
440 | clk_put(ac97->clk_ac97); | 446 | clk_put(ac97->clk_ac97); |
441 | err: | 447 | err: |
@@ -447,7 +453,7 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev) | |||
447 | struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev); | 453 | struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev); |
448 | 454 | ||
449 | tegra_pcm_platform_unregister(&pdev->dev); | 455 | tegra_pcm_platform_unregister(&pdev->dev); |
450 | snd_soc_unregister_dai(&pdev->dev); | 456 | snd_soc_unregister_component(&pdev->dev); |
451 | 457 | ||
452 | tegra_asoc_utils_fini(&ac97->util_data); | 458 | tegra_asoc_utils_fini(&ac97->util_data); |
453 | 459 | ||
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h index dddc6828004e..4acb3aaba29b 100644 --- a/sound/soc/tegra/tegra20_ac97.h +++ b/sound/soc/tegra/tegra20_ac97.h | |||
@@ -85,8 +85,8 @@ | |||
85 | 85 | ||
86 | struct tegra20_ac97 { | 86 | struct tegra20_ac97 { |
87 | struct clk *clk_ac97; | 87 | struct clk *clk_ac97; |
88 | struct tegra_pcm_dma_params capture_dma_data; | 88 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
89 | struct tegra_pcm_dma_params playback_dma_data; | 89 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
90 | struct regmap *regmap; | 90 | struct regmap *regmap; |
91 | int reset_gpio; | 91 | int reset_gpio; |
92 | int sync_gpio; | 92 | int sync_gpio; |
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index caa772de5a18..52af7f6fb37f 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <sound/pcm.h> | 41 | #include <sound/pcm.h> |
42 | #include <sound/pcm_params.h> | 42 | #include <sound/pcm_params.h> |
43 | #include <sound/soc.h> | 43 | #include <sound/soc.h> |
44 | #include <sound/dmaengine_pcm.h> | ||
44 | 45 | ||
45 | #include "tegra20_i2s.h" | 46 | #include "tegra20_i2s.h" |
46 | 47 | ||
@@ -276,6 +277,10 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { | |||
276 | .symmetric_rates = 1, | 277 | .symmetric_rates = 1, |
277 | }; | 278 | }; |
278 | 279 | ||
280 | static const struct snd_soc_component_driver tegra20_i2s_component = { | ||
281 | .name = DRV_NAME, | ||
282 | }; | ||
283 | |||
279 | static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) | 284 | static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) |
280 | { | 285 | { |
281 | switch (reg) { | 286 | switch (reg) { |
@@ -403,14 +408,14 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
403 | } | 408 | } |
404 | 409 | ||
405 | i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; | 410 | i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; |
406 | i2s->capture_dma_data.wrap = 4; | 411 | i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
407 | i2s->capture_dma_data.width = 32; | 412 | i2s->capture_dma_data.maxburst = 4; |
408 | i2s->capture_dma_data.req_sel = dma_ch; | 413 | i2s->capture_dma_data.slave_id = dma_ch; |
409 | 414 | ||
410 | i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; | 415 | i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; |
411 | i2s->playback_dma_data.wrap = 4; | 416 | i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
412 | i2s->playback_dma_data.width = 32; | 417 | i2s->playback_dma_data.maxburst = 4; |
413 | i2s->playback_dma_data.req_sel = dma_ch; | 418 | i2s->playback_dma_data.slave_id = dma_ch; |
414 | 419 | ||
415 | pm_runtime_enable(&pdev->dev); | 420 | pm_runtime_enable(&pdev->dev); |
416 | if (!pm_runtime_enabled(&pdev->dev)) { | 421 | if (!pm_runtime_enabled(&pdev->dev)) { |
@@ -419,7 +424,8 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
419 | goto err_pm_disable; | 424 | goto err_pm_disable; |
420 | } | 425 | } |
421 | 426 | ||
422 | ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); | 427 | ret = snd_soc_register_component(&pdev->dev, &tegra20_i2s_component, |
428 | &i2s->dai, 1); | ||
423 | if (ret) { | 429 | if (ret) { |
424 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | 430 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); |
425 | ret = -ENOMEM; | 431 | ret = -ENOMEM; |
@@ -429,13 +435,13 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) | |||
429 | ret = tegra_pcm_platform_register(&pdev->dev); | 435 | ret = tegra_pcm_platform_register(&pdev->dev); |
430 | if (ret) { | 436 | if (ret) { |
431 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | 437 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); |
432 | goto err_unregister_dai; | 438 | goto err_unregister_component; |
433 | } | 439 | } |
434 | 440 | ||
435 | return 0; | 441 | return 0; |
436 | 442 | ||
437 | err_unregister_dai: | 443 | err_unregister_component: |
438 | snd_soc_unregister_dai(&pdev->dev); | 444 | snd_soc_unregister_component(&pdev->dev); |
439 | err_suspend: | 445 | err_suspend: |
440 | if (!pm_runtime_status_suspended(&pdev->dev)) | 446 | if (!pm_runtime_status_suspended(&pdev->dev)) |
441 | tegra20_i2s_runtime_suspend(&pdev->dev); | 447 | tegra20_i2s_runtime_suspend(&pdev->dev); |
@@ -456,7 +462,7 @@ static int tegra20_i2s_platform_remove(struct platform_device *pdev) | |||
456 | tegra20_i2s_runtime_suspend(&pdev->dev); | 462 | tegra20_i2s_runtime_suspend(&pdev->dev); |
457 | 463 | ||
458 | tegra_pcm_platform_unregister(&pdev->dev); | 464 | tegra_pcm_platform_unregister(&pdev->dev); |
459 | snd_soc_unregister_dai(&pdev->dev); | 465 | snd_soc_unregister_component(&pdev->dev); |
460 | 466 | ||
461 | clk_put(i2s->clk_i2s); | 467 | clk_put(i2s->clk_i2s); |
462 | 468 | ||
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index 729958713cd4..fa6c29cc12b9 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h | |||
@@ -155,8 +155,8 @@ | |||
155 | struct tegra20_i2s { | 155 | struct tegra20_i2s { |
156 | struct snd_soc_dai_driver dai; | 156 | struct snd_soc_dai_driver dai; |
157 | struct clk *clk_i2s; | 157 | struct clk *clk_i2s; |
158 | struct tegra_pcm_dma_params capture_dma_data; | 158 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
159 | struct tegra_pcm_dma_params playback_dma_data; | 159 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
160 | struct regmap *regmap; | 160 | struct regmap *regmap; |
161 | }; | 161 | }; |
162 | 162 | ||
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 04771d14d343..5eaa12cdc6eb 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
33 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
34 | #include <sound/soc.h> | 34 | #include <sound/soc.h> |
35 | #include <sound/dmaengine_pcm.h> | ||
35 | 36 | ||
36 | #include "tegra20_spdif.h" | 37 | #include "tegra20_spdif.h" |
37 | 38 | ||
@@ -182,6 +183,10 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { | |||
182 | .ops = &tegra20_spdif_dai_ops, | 183 | .ops = &tegra20_spdif_dai_ops, |
183 | }; | 184 | }; |
184 | 185 | ||
186 | static const struct snd_soc_component_driver tegra20_spdif_component = { | ||
187 | .name = DRV_NAME, | ||
188 | }; | ||
189 | |||
185 | static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) | 190 | static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) |
186 | { | 191 | { |
187 | switch (reg) { | 192 | switch (reg) { |
@@ -318,9 +323,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) | |||
318 | } | 323 | } |
319 | 324 | ||
320 | spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; | 325 | spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; |
321 | spdif->playback_dma_data.wrap = 4; | 326 | spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
322 | spdif->playback_dma_data.width = 32; | 327 | spdif->capture_dma_data.maxburst = 4; |
323 | spdif->playback_dma_data.req_sel = dmareq->start; | 328 | spdif->playback_dma_data.slave_id = dmareq->start; |
324 | 329 | ||
325 | pm_runtime_enable(&pdev->dev); | 330 | pm_runtime_enable(&pdev->dev); |
326 | if (!pm_runtime_enabled(&pdev->dev)) { | 331 | if (!pm_runtime_enabled(&pdev->dev)) { |
@@ -329,7 +334,8 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) | |||
329 | goto err_pm_disable; | 334 | goto err_pm_disable; |
330 | } | 335 | } |
331 | 336 | ||
332 | ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai); | 337 | ret = snd_soc_register_component(&pdev->dev, &tegra20_spdif_component, |
338 | &tegra20_spdif_dai, 1); | ||
333 | if (ret) { | 339 | if (ret) { |
334 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | 340 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); |
335 | ret = -ENOMEM; | 341 | ret = -ENOMEM; |
@@ -339,13 +345,13 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) | |||
339 | ret = tegra_pcm_platform_register(&pdev->dev); | 345 | ret = tegra_pcm_platform_register(&pdev->dev); |
340 | if (ret) { | 346 | if (ret) { |
341 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | 347 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); |
342 | goto err_unregister_dai; | 348 | goto err_unregister_component; |
343 | } | 349 | } |
344 | 350 | ||
345 | return 0; | 351 | return 0; |
346 | 352 | ||
347 | err_unregister_dai: | 353 | err_unregister_component: |
348 | snd_soc_unregister_dai(&pdev->dev); | 354 | snd_soc_unregister_component(&pdev->dev); |
349 | err_suspend: | 355 | err_suspend: |
350 | if (!pm_runtime_status_suspended(&pdev->dev)) | 356 | if (!pm_runtime_status_suspended(&pdev->dev)) |
351 | tegra20_spdif_runtime_suspend(&pdev->dev); | 357 | tegra20_spdif_runtime_suspend(&pdev->dev); |
@@ -366,7 +372,7 @@ static int tegra20_spdif_platform_remove(struct platform_device *pdev) | |||
366 | tegra20_spdif_runtime_suspend(&pdev->dev); | 372 | tegra20_spdif_runtime_suspend(&pdev->dev); |
367 | 373 | ||
368 | tegra_pcm_platform_unregister(&pdev->dev); | 374 | tegra_pcm_platform_unregister(&pdev->dev); |
369 | snd_soc_unregister_dai(&pdev->dev); | 375 | snd_soc_unregister_component(&pdev->dev); |
370 | 376 | ||
371 | clk_put(spdif->clk_spdif_out); | 377 | clk_put(spdif->clk_spdif_out); |
372 | 378 | ||
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h index b48d699fd583..85a9aefcc287 100644 --- a/sound/soc/tegra/tegra20_spdif.h +++ b/sound/soc/tegra/tegra20_spdif.h | |||
@@ -462,8 +462,8 @@ | |||
462 | 462 | ||
463 | struct tegra20_spdif { | 463 | struct tegra20_spdif { |
464 | struct clk *clk_spdif_out; | 464 | struct clk *clk_spdif_out; |
465 | struct tegra_pcm_dma_params capture_dma_data; | 465 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
466 | struct tegra_pcm_dma_params playback_dma_data; | 466 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
467 | struct regmap *regmap; | 467 | struct regmap *regmap; |
468 | }; | 468 | }; |
469 | 469 | ||
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index e5cfb4ac41ba..23e592f453fa 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c | |||
@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, | 97 | int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, |
98 | unsigned long *fiforeg, | 98 | dma_addr_t *fiforeg, |
99 | unsigned long *reqsel) | 99 | unsigned int *reqsel) |
100 | { | 100 | { |
101 | int channel; | 101 | int channel; |
102 | u32 reg, val; | 102 | u32 reg, val; |
@@ -178,8 +178,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif) | |||
178 | EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); | 178 | EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); |
179 | 179 | ||
180 | int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, | 180 | int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, |
181 | unsigned long *fiforeg, | 181 | dma_addr_t *fiforeg, |
182 | unsigned long *reqsel) | 182 | unsigned int *reqsel) |
183 | { | 183 | { |
184 | int channel; | 184 | int channel; |
185 | u32 reg, val; | 185 | u32 reg, val; |
@@ -287,16 +287,27 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) | |||
287 | } | 287 | } |
288 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); | 288 | EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); |
289 | 289 | ||
290 | static const char * const configlink_clocks[] = { | 290 | #define CLK_LIST_MASK_TEGRA30 BIT(0) |
291 | "i2s0", | 291 | #define CLK_LIST_MASK_TEGRA114 BIT(1) |
292 | "i2s1", | 292 | |
293 | "i2s2", | 293 | #define CLK_LIST_MASK_TEGRA30_OR_LATER \ |
294 | "i2s3", | 294 | (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114) |
295 | "i2s4", | 295 | |
296 | "dam0", | 296 | static const struct { |
297 | "dam1", | 297 | const char *clk_name; |
298 | "dam2", | 298 | u32 clk_list_mask; |
299 | "spdif_in", | 299 | } configlink_clocks[] = { |
300 | { "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
301 | { "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
302 | { "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
303 | { "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
304 | { "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
305 | { "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
306 | { "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
307 | { "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
308 | { "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER }, | ||
309 | { "amx", CLK_LIST_MASK_TEGRA114 }, | ||
310 | { "adx", CLK_LIST_MASK_TEGRA114 }, | ||
300 | }; | 311 | }; |
301 | 312 | ||
302 | #define LAST_REG(name) \ | 313 | #define LAST_REG(name) \ |
@@ -424,8 +435,24 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { | |||
424 | .cache_type = REGCACHE_RBTREE, | 435 | .cache_type = REGCACHE_RBTREE, |
425 | }; | 436 | }; |
426 | 437 | ||
438 | static struct tegra30_ahub_soc_data soc_data_tegra30 = { | ||
439 | .clk_list_mask = CLK_LIST_MASK_TEGRA30, | ||
440 | }; | ||
441 | |||
442 | static struct tegra30_ahub_soc_data soc_data_tegra114 = { | ||
443 | .clk_list_mask = CLK_LIST_MASK_TEGRA114, | ||
444 | }; | ||
445 | |||
446 | static const struct of_device_id tegra30_ahub_of_match[] = { | ||
447 | { .compatible = "nvidia,tegra114-ahub", .data = &soc_data_tegra114 }, | ||
448 | { .compatible = "nvidia,tegra30-ahub", .data = &soc_data_tegra30 }, | ||
449 | {}, | ||
450 | }; | ||
451 | |||
427 | static int tegra30_ahub_probe(struct platform_device *pdev) | 452 | static int tegra30_ahub_probe(struct platform_device *pdev) |
428 | { | 453 | { |
454 | const struct of_device_id *match; | ||
455 | const struct tegra30_ahub_soc_data *soc_data; | ||
429 | struct clk *clk; | 456 | struct clk *clk; |
430 | int i; | 457 | int i; |
431 | struct resource *res0, *res1, *region; | 458 | struct resource *res0, *res1, *region; |
@@ -436,16 +463,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev) | |||
436 | if (ahub) | 463 | if (ahub) |
437 | return -ENODEV; | 464 | return -ENODEV; |
438 | 465 | ||
466 | match = of_match_device(tegra30_ahub_of_match, &pdev->dev); | ||
467 | if (!match) | ||
468 | return -EINVAL; | ||
469 | soc_data = match->data; | ||
470 | |||
439 | /* | 471 | /* |
440 | * The AHUB hosts a register bus: the "configlink". For this to | 472 | * The AHUB hosts a register bus: the "configlink". For this to |
441 | * operate correctly, all devices on this bus must be out of reset. | 473 | * operate correctly, all devices on this bus must be out of reset. |
442 | * Ensure that here. | 474 | * Ensure that here. |
443 | */ | 475 | */ |
444 | for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { | 476 | for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { |
445 | clk = clk_get(&pdev->dev, configlink_clocks[i]); | 477 | if (!(configlink_clocks[i].clk_list_mask & |
478 | soc_data->clk_list_mask)) | ||
479 | continue; | ||
480 | clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name); | ||
446 | if (IS_ERR(clk)) { | 481 | if (IS_ERR(clk)) { |
447 | dev_err(&pdev->dev, "Can't get clock %s\n", | 482 | dev_err(&pdev->dev, "Can't get clock %s\n", |
448 | configlink_clocks[i]); | 483 | configlink_clocks[i].clk_name); |
449 | ret = PTR_ERR(clk); | 484 | ret = PTR_ERR(clk); |
450 | goto err; | 485 | goto err; |
451 | } | 486 | } |
@@ -592,11 +627,6 @@ static int tegra30_ahub_remove(struct platform_device *pdev) | |||
592 | return 0; | 627 | return 0; |
593 | } | 628 | } |
594 | 629 | ||
595 | static const struct of_device_id tegra30_ahub_of_match[] = { | ||
596 | { .compatible = "nvidia,tegra30-ahub", }, | ||
597 | {}, | ||
598 | }; | ||
599 | |||
600 | static const struct dev_pm_ops tegra30_ahub_pm_ops = { | 630 | static const struct dev_pm_ops tegra30_ahub_pm_ops = { |
601 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, | 631 | SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, |
602 | tegra30_ahub_runtime_resume, NULL) | 632 | tegra30_ahub_runtime_resume, NULL) |
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index e690e2eecc92..09766cdc45ca 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h | |||
@@ -451,15 +451,15 @@ enum tegra30_ahub_rxcif { | |||
451 | }; | 451 | }; |
452 | 452 | ||
453 | extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, | 453 | extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, |
454 | unsigned long *fiforeg, | 454 | dma_addr_t *fiforeg, |
455 | unsigned long *reqsel); | 455 | unsigned int *reqsel); |
456 | extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); | 456 | extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); |
457 | extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); | 457 | extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); |
458 | extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); | 458 | extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); |
459 | 459 | ||
460 | extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, | 460 | extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, |
461 | unsigned long *fiforeg, | 461 | dma_addr_t *fiforeg, |
462 | unsigned long *reqsel); | 462 | unsigned int *reqsel); |
463 | extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); | 463 | extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); |
464 | extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); | 464 | extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); |
465 | extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); | 465 | extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); |
@@ -468,7 +468,23 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, | |||
468 | enum tegra30_ahub_txcif txcif); | 468 | enum tegra30_ahub_txcif txcif); |
469 | extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); | 469 | extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); |
470 | 470 | ||
471 | struct tegra30_ahub_soc_data { | ||
472 | u32 clk_list_mask; | ||
473 | /* | ||
474 | * FIXME: There are many more differences in HW, such as: | ||
475 | * - More APBIF channels. | ||
476 | * - Extra separate chunks of register address space to represent | ||
477 | * the extra APBIF channels. | ||
478 | * - More units connected to the AHUB, so that tegra30_ahub_[rt]xcif | ||
479 | * need expansion, coupled with there being more defined bits in | ||
480 | * the AHUB routing registers. | ||
481 | * However, the driver doesn't support those new features yet, so we | ||
482 | * don't represent them here yet. | ||
483 | */ | ||
484 | }; | ||
485 | |||
471 | struct tegra30_ahub { | 486 | struct tegra30_ahub { |
487 | const struct tegra30_ahub_soc_data *soc_data; | ||
472 | struct device *dev; | 488 | struct device *dev; |
473 | struct clk *clk_d_audio; | 489 | struct clk *clk_d_audio; |
474 | struct clk *clk_apbif; | 490 | struct clk *clk_apbif; |
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index f4e1ce82750a..31d092d83c71 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <sound/pcm.h> | 38 | #include <sound/pcm.h> |
39 | #include <sound/pcm_params.h> | 39 | #include <sound/pcm_params.h> |
40 | #include <sound/soc.h> | 40 | #include <sound/soc.h> |
41 | #include <sound/dmaengine_pcm.h> | ||
41 | 42 | ||
42 | #include "tegra30_ahub.h" | 43 | #include "tegra30_ahub.h" |
43 | #include "tegra30_i2s.h" | 44 | #include "tegra30_i2s.h" |
@@ -80,17 +81,17 @@ static int tegra30_i2s_startup(struct snd_pcm_substream *substream, | |||
80 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 81 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
81 | ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, | 82 | ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, |
82 | &i2s->playback_dma_data.addr, | 83 | &i2s->playback_dma_data.addr, |
83 | &i2s->playback_dma_data.req_sel); | 84 | &i2s->playback_dma_data.slave_id); |
84 | i2s->playback_dma_data.wrap = 4; | 85 | i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
85 | i2s->playback_dma_data.width = 32; | 86 | i2s->playback_dma_data.maxburst = 4; |
86 | tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, | 87 | tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, |
87 | i2s->playback_fifo_cif); | 88 | i2s->playback_fifo_cif); |
88 | } else { | 89 | } else { |
89 | ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, | 90 | ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, |
90 | &i2s->capture_dma_data.addr, | 91 | &i2s->capture_dma_data.addr, |
91 | &i2s->capture_dma_data.req_sel); | 92 | &i2s->capture_dma_data.slave_id); |
92 | i2s->capture_dma_data.wrap = 4; | 93 | i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
93 | i2s->capture_dma_data.width = 32; | 94 | i2s->capture_dma_data.maxburst = 4; |
94 | tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, | 95 | tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, |
95 | i2s->capture_i2s_cif); | 96 | i2s->capture_i2s_cif); |
96 | } | 97 | } |
@@ -336,6 +337,10 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { | |||
336 | .symmetric_rates = 1, | 337 | .symmetric_rates = 1, |
337 | }; | 338 | }; |
338 | 339 | ||
340 | static const struct snd_soc_component_driver tegra30_i2s_component = { | ||
341 | .name = DRV_NAME, | ||
342 | }; | ||
343 | |||
339 | static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) | 344 | static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) |
340 | { | 345 | { |
341 | switch (reg) { | 346 | switch (reg) { |
@@ -464,7 +469,8 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) | |||
464 | goto err_pm_disable; | 469 | goto err_pm_disable; |
465 | } | 470 | } |
466 | 471 | ||
467 | ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); | 472 | ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, |
473 | &i2s->dai, 1); | ||
468 | if (ret) { | 474 | if (ret) { |
469 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | 475 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); |
470 | ret = -ENOMEM; | 476 | ret = -ENOMEM; |
@@ -474,13 +480,13 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) | |||
474 | ret = tegra_pcm_platform_register(&pdev->dev); | 480 | ret = tegra_pcm_platform_register(&pdev->dev); |
475 | if (ret) { | 481 | if (ret) { |
476 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | 482 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); |
477 | goto err_unregister_dai; | 483 | goto err_unregister_component; |
478 | } | 484 | } |
479 | 485 | ||
480 | return 0; | 486 | return 0; |
481 | 487 | ||
482 | err_unregister_dai: | 488 | err_unregister_component: |
483 | snd_soc_unregister_dai(&pdev->dev); | 489 | snd_soc_unregister_component(&pdev->dev); |
484 | err_suspend: | 490 | err_suspend: |
485 | if (!pm_runtime_status_suspended(&pdev->dev)) | 491 | if (!pm_runtime_status_suspended(&pdev->dev)) |
486 | tegra30_i2s_runtime_suspend(&pdev->dev); | 492 | tegra30_i2s_runtime_suspend(&pdev->dev); |
@@ -501,7 +507,7 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) | |||
501 | tegra30_i2s_runtime_suspend(&pdev->dev); | 507 | tegra30_i2s_runtime_suspend(&pdev->dev); |
502 | 508 | ||
503 | tegra_pcm_platform_unregister(&pdev->dev); | 509 | tegra_pcm_platform_unregister(&pdev->dev); |
504 | snd_soc_unregister_dai(&pdev->dev); | 510 | snd_soc_unregister_component(&pdev->dev); |
505 | 511 | ||
506 | clk_put(i2s->clk_i2s); | 512 | clk_put(i2s->clk_i2s); |
507 | 513 | ||
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index a294d942b9f7..bea23afe3b9f 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h | |||
@@ -231,10 +231,10 @@ struct tegra30_i2s { | |||
231 | struct clk *clk_i2s; | 231 | struct clk *clk_i2s; |
232 | enum tegra30_ahub_txcif capture_i2s_cif; | 232 | enum tegra30_ahub_txcif capture_i2s_cif; |
233 | enum tegra30_ahub_rxcif capture_fifo_cif; | 233 | enum tegra30_ahub_rxcif capture_fifo_cif; |
234 | struct tegra_pcm_dma_params capture_dma_data; | 234 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
235 | enum tegra30_ahub_rxcif playback_i2s_cif; | 235 | enum tegra30_ahub_rxcif playback_i2s_cif; |
236 | enum tegra30_ahub_txcif playback_fifo_cif; | 236 | enum tegra30_ahub_txcif playback_fifo_cif; |
237 | struct tegra_pcm_dma_params playback_dma_data; | 237 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
238 | struct regmap *regmap; | 238 | struct regmap *regmap; |
239 | }; | 239 | }; |
240 | 240 | ||
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index c80adb9da472..48d05d9e1002 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -161,20 +161,13 @@ static int tegra_alc5632_probe(struct platform_device *pdev) | |||
161 | sizeof(struct tegra_alc5632), GFP_KERNEL); | 161 | sizeof(struct tegra_alc5632), GFP_KERNEL); |
162 | if (!alc5632) { | 162 | if (!alc5632) { |
163 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); | 163 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); |
164 | ret = -ENOMEM; | 164 | return -ENOMEM; |
165 | goto err; | ||
166 | } | 165 | } |
167 | 166 | ||
168 | card->dev = &pdev->dev; | 167 | card->dev = &pdev->dev; |
169 | platform_set_drvdata(pdev, card); | 168 | platform_set_drvdata(pdev, card); |
170 | snd_soc_card_set_drvdata(card, alc5632); | 169 | snd_soc_card_set_drvdata(card, alc5632); |
171 | 170 | ||
172 | if (!(pdev->dev.of_node)) { | ||
173 | dev_err(&pdev->dev, "Must be instantiated using device tree\n"); | ||
174 | ret = -EINVAL; | ||
175 | goto err; | ||
176 | } | ||
177 | |||
178 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | 171 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); |
179 | if (alc5632->gpio_hp_det == -EPROBE_DEFER) | 172 | if (alc5632->gpio_hp_det == -EPROBE_DEFER) |
180 | return -EPROBE_DEFER; | 173 | return -EPROBE_DEFER; |
@@ -197,11 +190,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev) | |||
197 | goto err; | 190 | goto err; |
198 | } | 191 | } |
199 | 192 | ||
200 | tegra_alc5632_dai.cpu_of_node = of_parse_phandle( | 193 | tegra_alc5632_dai.cpu_of_node = of_parse_phandle(np, |
201 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 194 | "nvidia,i2s-controller", 0); |
202 | if (!tegra_alc5632_dai.cpu_of_node) { | 195 | if (!tegra_alc5632_dai.cpu_of_node) { |
203 | dev_err(&pdev->dev, | 196 | dev_err(&pdev->dev, |
204 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 197 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
205 | ret = -EINVAL; | 198 | ret = -EINVAL; |
206 | goto err; | 199 | goto err; |
207 | } | 200 | } |
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index ba419f86384d..24fb001be7f4 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c | |||
@@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, | |||
43 | case 88200: | 43 | case 88200: |
44 | if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) | 44 | if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) |
45 | new_baseclock = 56448000; | 45 | new_baseclock = 56448000; |
46 | else | 46 | else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) |
47 | new_baseclock = 564480000; | 47 | new_baseclock = 564480000; |
48 | else | ||
49 | new_baseclock = 282240000; | ||
48 | break; | 50 | break; |
49 | case 8000: | 51 | case 8000: |
50 | case 16000: | 52 | case 16000: |
@@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, | |||
54 | case 96000: | 56 | case 96000: |
55 | if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) | 57 | if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) |
56 | new_baseclock = 73728000; | 58 | new_baseclock = 73728000; |
57 | else | 59 | else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) |
58 | new_baseclock = 552960000; | 60 | new_baseclock = 552960000; |
61 | else | ||
62 | new_baseclock = 368640000; | ||
59 | break; | 63 | break; |
60 | default: | 64 | default: |
61 | return -EINVAL; | 65 | return -EINVAL; |
@@ -169,6 +173,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, | |||
169 | struct device *dev) | 173 | struct device *dev) |
170 | { | 174 | { |
171 | int ret; | 175 | int ret; |
176 | bool new_clocks = false; | ||
172 | 177 | ||
173 | data->dev = dev; | 178 | data->dev = dev; |
174 | 179 | ||
@@ -176,28 +181,37 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, | |||
176 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; | 181 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; |
177 | else if (of_machine_is_compatible("nvidia,tegra30")) | 182 | else if (of_machine_is_compatible("nvidia,tegra30")) |
178 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; | 183 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; |
179 | else if (!dev->of_node) | 184 | else if (of_machine_is_compatible("nvidia,tegra114")) { |
180 | /* non-DT is always Tegra20 */ | 185 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; |
181 | data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; | 186 | new_clocks = true; |
182 | else | 187 | } else { |
183 | /* DT boot, but unknown SoC */ | 188 | dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); |
184 | return -EINVAL; | 189 | return -EINVAL; |
190 | } | ||
185 | 191 | ||
186 | data->clk_pll_a = clk_get_sys(NULL, "pll_a"); | 192 | if (new_clocks) |
193 | data->clk_pll_a = clk_get(dev, "pll_a"); | ||
194 | else | ||
195 | data->clk_pll_a = clk_get_sys(NULL, "pll_a"); | ||
187 | if (IS_ERR(data->clk_pll_a)) { | 196 | if (IS_ERR(data->clk_pll_a)) { |
188 | dev_err(data->dev, "Can't retrieve clk pll_a\n"); | 197 | dev_err(data->dev, "Can't retrieve clk pll_a\n"); |
189 | ret = PTR_ERR(data->clk_pll_a); | 198 | ret = PTR_ERR(data->clk_pll_a); |
190 | goto err; | 199 | goto err; |
191 | } | 200 | } |
192 | 201 | ||
193 | data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); | 202 | if (new_clocks) |
203 | data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0"); | ||
204 | else | ||
205 | data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); | ||
194 | if (IS_ERR(data->clk_pll_a_out0)) { | 206 | if (IS_ERR(data->clk_pll_a_out0)) { |
195 | dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); | 207 | dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); |
196 | ret = PTR_ERR(data->clk_pll_a_out0); | 208 | ret = PTR_ERR(data->clk_pll_a_out0); |
197 | goto err_put_pll_a; | 209 | goto err_put_pll_a; |
198 | } | 210 | } |
199 | 211 | ||
200 | if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) | 212 | if (new_clocks) |
213 | data->clk_cdev1 = clk_get(dev, "mclk"); | ||
214 | else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) | ||
201 | data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); | 215 | data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); |
202 | else | 216 | else |
203 | data->clk_cdev1 = clk_get_sys("extern1", NULL); | 217 | data->clk_cdev1 = clk_get_sys("extern1", NULL); |
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 974c9f8830f9..19fdcafed32f 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h | |||
@@ -29,6 +29,7 @@ struct device; | |||
29 | enum tegra_asoc_utils_soc { | 29 | enum tegra_asoc_utils_soc { |
30 | TEGRA_ASOC_UTILS_SOC_TEGRA20, | 30 | TEGRA_ASOC_UTILS_SOC_TEGRA20, |
31 | TEGRA_ASOC_UTILS_SOC_TEGRA30, | 31 | TEGRA_ASOC_UTILS_SOC_TEGRA30, |
32 | TEGRA_ASOC_UTILS_SOC_TEGRA114, | ||
32 | }; | 33 | }; |
33 | 34 | ||
34 | struct tegra_asoc_utils_data { | 35 | struct tegra_asoc_utils_data { |
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 5e2c55c5b255..f056f632557c 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c | |||
@@ -29,9 +29,7 @@ | |||
29 | * | 29 | * |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
34 | #include <linux/slab.h> | ||
35 | #include <sound/core.h> | 33 | #include <sound/core.h> |
36 | #include <sound/pcm.h> | 34 | #include <sound/pcm.h> |
37 | #include <sound/pcm_params.h> | 35 | #include <sound/pcm_params.h> |
@@ -55,191 +53,24 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { | |||
55 | .fifo_size = 4, | 53 | .fifo_size = 4, |
56 | }; | 54 | }; |
57 | 55 | ||
58 | static int tegra_pcm_open(struct snd_pcm_substream *substream) | 56 | static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = { |
59 | { | 57 | .pcm_hardware = &tegra_pcm_hardware, |
60 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 58 | .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, |
61 | struct device *dev = rtd->platform->dev; | 59 | .compat_filter_fn = NULL, |
62 | int ret; | 60 | .prealloc_buffer_size = PAGE_SIZE * 8, |
63 | |||
64 | /* Set HW params now that initialization is complete */ | ||
65 | snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); | ||
66 | |||
67 | ret = snd_dmaengine_pcm_open(substream, NULL, NULL); | ||
68 | if (ret) { | ||
69 | dev_err(dev, "dmaengine pcm open failed with err %d\n", ret); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int tegra_pcm_close(struct snd_pcm_substream *substream) | ||
77 | { | ||
78 | snd_dmaengine_pcm_close(substream); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, | ||
83 | struct snd_pcm_hw_params *params) | ||
84 | { | ||
85 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
86 | struct device *dev = rtd->platform->dev; | ||
87 | struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); | ||
88 | struct tegra_pcm_dma_params *dmap; | ||
89 | struct dma_slave_config slave_config; | ||
90 | int ret; | ||
91 | |||
92 | dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
93 | |||
94 | ret = snd_hwparams_to_dma_slave_config(substream, params, | ||
95 | &slave_config); | ||
96 | if (ret) { | ||
97 | dev_err(dev, "hw params config failed with err %d\n", ret); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
102 | slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
103 | slave_config.dst_addr = dmap->addr; | ||
104 | slave_config.dst_maxburst = 4; | ||
105 | } else { | ||
106 | slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
107 | slave_config.src_addr = dmap->addr; | ||
108 | slave_config.src_maxburst = 4; | ||
109 | } | ||
110 | slave_config.slave_id = dmap->req_sel; | ||
111 | |||
112 | ret = dmaengine_slave_config(chan, &slave_config); | ||
113 | if (ret < 0) { | ||
114 | dev_err(dev, "dma slave config failed with err %d\n", ret); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int tegra_pcm_hw_free(struct snd_pcm_substream *substream) | ||
123 | { | ||
124 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int tegra_pcm_mmap(struct snd_pcm_substream *substream, | ||
129 | struct vm_area_struct *vma) | ||
130 | { | ||
131 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
132 | |||
133 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
134 | runtime->dma_area, | ||
135 | runtime->dma_addr, | ||
136 | runtime->dma_bytes); | ||
137 | } | ||
138 | |||
139 | static struct snd_pcm_ops tegra_pcm_ops = { | ||
140 | .open = tegra_pcm_open, | ||
141 | .close = tegra_pcm_close, | ||
142 | .ioctl = snd_pcm_lib_ioctl, | ||
143 | .hw_params = tegra_pcm_hw_params, | ||
144 | .hw_free = tegra_pcm_hw_free, | ||
145 | .trigger = snd_dmaengine_pcm_trigger, | ||
146 | .pointer = snd_dmaengine_pcm_pointer, | ||
147 | .mmap = tegra_pcm_mmap, | ||
148 | }; | ||
149 | |||
150 | static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
151 | { | ||
152 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
153 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
154 | size_t size = tegra_pcm_hardware.buffer_bytes_max; | ||
155 | |||
156 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
157 | &buf->addr, GFP_KERNEL); | ||
158 | if (!buf->area) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
162 | buf->dev.dev = pcm->card->dev; | ||
163 | buf->private_data = NULL; | ||
164 | buf->bytes = size; | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
170 | { | ||
171 | struct snd_pcm_substream *substream; | ||
172 | struct snd_dma_buffer *buf; | ||
173 | |||
174 | substream = pcm->streams[stream].substream; | ||
175 | if (!substream) | ||
176 | return; | ||
177 | |||
178 | buf = &substream->dma_buffer; | ||
179 | if (!buf->area) | ||
180 | return; | ||
181 | |||
182 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
183 | buf->area, buf->addr); | ||
184 | buf->area = NULL; | ||
185 | } | ||
186 | |||
187 | static u64 tegra_dma_mask = DMA_BIT_MASK(32); | ||
188 | |||
189 | static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
190 | { | ||
191 | struct snd_card *card = rtd->card->snd_card; | ||
192 | struct snd_pcm *pcm = rtd->pcm; | ||
193 | int ret = 0; | ||
194 | |||
195 | if (!card->dev->dma_mask) | ||
196 | card->dev->dma_mask = &tegra_dma_mask; | ||
197 | if (!card->dev->coherent_dma_mask) | ||
198 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
199 | |||
200 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
201 | ret = tegra_pcm_preallocate_dma_buffer(pcm, | ||
202 | SNDRV_PCM_STREAM_PLAYBACK); | ||
203 | if (ret) | ||
204 | goto err; | ||
205 | } | ||
206 | |||
207 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
208 | ret = tegra_pcm_preallocate_dma_buffer(pcm, | ||
209 | SNDRV_PCM_STREAM_CAPTURE); | ||
210 | if (ret) | ||
211 | goto err_free_play; | ||
212 | } | ||
213 | |||
214 | return 0; | ||
215 | |||
216 | err_free_play: | ||
217 | tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); | ||
218 | err: | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | static void tegra_pcm_free(struct snd_pcm *pcm) | ||
223 | { | ||
224 | tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); | ||
225 | tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); | ||
226 | } | ||
227 | |||
228 | static struct snd_soc_platform_driver tegra_pcm_platform = { | ||
229 | .ops = &tegra_pcm_ops, | ||
230 | .pcm_new = tegra_pcm_new, | ||
231 | .pcm_free = tegra_pcm_free, | ||
232 | }; | 61 | }; |
233 | 62 | ||
234 | int tegra_pcm_platform_register(struct device *dev) | 63 | int tegra_pcm_platform_register(struct device *dev) |
235 | { | 64 | { |
236 | return snd_soc_register_platform(dev, &tegra_pcm_platform); | 65 | return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, |
66 | SND_DMAENGINE_PCM_FLAG_NO_DT | | ||
67 | SND_DMAENGINE_PCM_FLAG_COMPAT); | ||
237 | } | 68 | } |
238 | EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); | 69 | EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); |
239 | 70 | ||
240 | void tegra_pcm_platform_unregister(struct device *dev) | 71 | void tegra_pcm_platform_unregister(struct device *dev) |
241 | { | 72 | { |
242 | snd_soc_unregister_platform(dev); | 73 | return snd_dmaengine_pcm_unregister(dev); |
243 | } | 74 | } |
244 | EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister); | 75 | EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister); |
245 | 76 | ||
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h index bc8b46af928e..68ad901714a9 100644 --- a/sound/soc/tegra/tegra_pcm.h +++ b/sound/soc/tegra/tegra_pcm.h | |||
@@ -31,13 +31,6 @@ | |||
31 | #ifndef __TEGRA_PCM_H__ | 31 | #ifndef __TEGRA_PCM_H__ |
32 | #define __TEGRA_PCM_H__ | 32 | #define __TEGRA_PCM_H__ |
33 | 33 | ||
34 | struct tegra_pcm_dma_params { | ||
35 | unsigned long addr; | ||
36 | unsigned long wrap; | ||
37 | unsigned long width; | ||
38 | unsigned long req_sel; | ||
39 | }; | ||
40 | |||
41 | int tegra_pcm_platform_register(struct device *dev); | 34 | int tegra_pcm_platform_register(struct device *dev); |
42 | void tegra_pcm_platform_unregister(struct device *dev); | 35 | void tegra_pcm_platform_unregister(struct device *dev); |
43 | 36 | ||
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index c8ef88a67c59..f87fc53e9b8c 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c | |||
@@ -124,6 +124,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = { | |||
124 | 124 | ||
125 | static int tegra_wm8753_driver_probe(struct platform_device *pdev) | 125 | static int tegra_wm8753_driver_probe(struct platform_device *pdev) |
126 | { | 126 | { |
127 | struct device_node *np = pdev->dev.of_node; | ||
127 | struct snd_soc_card *card = &snd_soc_tegra_wm8753; | 128 | struct snd_soc_card *card = &snd_soc_tegra_wm8753; |
128 | struct tegra_wm8753 *machine; | 129 | struct tegra_wm8753 *machine; |
129 | int ret; | 130 | int ret; |
@@ -132,8 +133,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
132 | GFP_KERNEL); | 133 | GFP_KERNEL); |
133 | if (!machine) { | 134 | if (!machine) { |
134 | dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n"); | 135 | dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n"); |
135 | ret = -ENOMEM; | 136 | return -ENOMEM; |
136 | goto err; | ||
137 | } | 137 | } |
138 | 138 | ||
139 | card->dev = &pdev->dev; | 139 | card->dev = &pdev->dev; |
@@ -148,8 +148,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
148 | if (ret) | 148 | if (ret) |
149 | goto err; | 149 | goto err; |
150 | 150 | ||
151 | tegra_wm8753_dai.codec_of_node = of_parse_phandle( | 151 | tegra_wm8753_dai.codec_of_node = of_parse_phandle(np, |
152 | pdev->dev.of_node, "nvidia,audio-codec", 0); | 152 | "nvidia,audio-codec", 0); |
153 | if (!tegra_wm8753_dai.codec_of_node) { | 153 | if (!tegra_wm8753_dai.codec_of_node) { |
154 | dev_err(&pdev->dev, | 154 | dev_err(&pdev->dev, |
155 | "Property 'nvidia,audio-codec' missing or invalid\n"); | 155 | "Property 'nvidia,audio-codec' missing or invalid\n"); |
@@ -157,8 +157,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
157 | goto err; | 157 | goto err; |
158 | } | 158 | } |
159 | 159 | ||
160 | tegra_wm8753_dai.cpu_of_node = of_parse_phandle( | 160 | tegra_wm8753_dai.cpu_of_node = of_parse_phandle(np, |
161 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | 161 | "nvidia,i2s-controller", 0); |
162 | if (!tegra_wm8753_dai.cpu_of_node) { | 162 | if (!tegra_wm8753_dai.cpu_of_node) { |
163 | dev_err(&pdev->dev, | 163 | dev_err(&pdev->dev, |
164 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | 164 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
@@ -166,8 +166,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) | |||
166 | goto err; | 166 | goto err; |
167 | } | 167 | } |
168 | 168 | ||
169 | tegra_wm8753_dai.platform_of_node = | 169 | tegra_wm8753_dai.platform_of_node = tegra_wm8753_dai.cpu_of_node; |
170 | tegra_wm8753_dai.cpu_of_node; | ||
171 | 170 | ||
172 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | 171 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); |
173 | if (ret) | 172 | if (ret) |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index bbd79bf56303..4ac73730d79a 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <sound/pcm.h> | 39 | #include <sound/pcm.h> |
40 | #include <sound/pcm_params.h> | 40 | #include <sound/pcm_params.h> |
41 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | #include <sound/tegra_wm8903.h> | ||
43 | 42 | ||
44 | #include "../codecs/wm8903.h" | 43 | #include "../codecs/wm8903.h" |
45 | 44 | ||
@@ -48,7 +47,11 @@ | |||
48 | #define DRV_NAME "tegra-snd-wm8903" | 47 | #define DRV_NAME "tegra-snd-wm8903" |
49 | 48 | ||
50 | struct tegra_wm8903 { | 49 | struct tegra_wm8903 { |
51 | struct tegra_wm8903_platform_data pdata; | 50 | int gpio_spkr_en; |
51 | int gpio_hp_det; | ||
52 | int gpio_hp_mute; | ||
53 | int gpio_int_mic_en; | ||
54 | int gpio_ext_mic_en; | ||
52 | struct tegra_asoc_utils_data util_data; | 55 | struct tegra_asoc_utils_data util_data; |
53 | }; | 56 | }; |
54 | 57 | ||
@@ -129,12 +132,11 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, | |||
129 | struct snd_soc_dapm_context *dapm = w->dapm; | 132 | struct snd_soc_dapm_context *dapm = w->dapm; |
130 | struct snd_soc_card *card = dapm->card; | 133 | struct snd_soc_card *card = dapm->card; |
131 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 134 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
132 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
133 | 135 | ||
134 | if (!gpio_is_valid(pdata->gpio_spkr_en)) | 136 | if (!gpio_is_valid(machine->gpio_spkr_en)) |
135 | return 0; | 137 | return 0; |
136 | 138 | ||
137 | gpio_set_value_cansleep(pdata->gpio_spkr_en, | 139 | gpio_set_value_cansleep(machine->gpio_spkr_en, |
138 | SND_SOC_DAPM_EVENT_ON(event)); | 140 | SND_SOC_DAPM_EVENT_ON(event)); |
139 | 141 | ||
140 | return 0; | 142 | return 0; |
@@ -146,12 +148,11 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, | |||
146 | struct snd_soc_dapm_context *dapm = w->dapm; | 148 | struct snd_soc_dapm_context *dapm = w->dapm; |
147 | struct snd_soc_card *card = dapm->card; | 149 | struct snd_soc_card *card = dapm->card; |
148 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 150 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
149 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
150 | 151 | ||
151 | if (!gpio_is_valid(pdata->gpio_hp_mute)) | 152 | if (!gpio_is_valid(machine->gpio_hp_mute)) |
152 | return 0; | 153 | return 0; |
153 | 154 | ||
154 | gpio_set_value_cansleep(pdata->gpio_hp_mute, | 155 | gpio_set_value_cansleep(machine->gpio_hp_mute, |
155 | !SND_SOC_DAPM_EVENT_ON(event)); | 156 | !SND_SOC_DAPM_EVENT_ON(event)); |
156 | 157 | ||
157 | return 0; | 158 | return 0; |
@@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { | |||
163 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | 164 | SND_SOC_DAPM_MIC("Mic Jack", NULL), |
164 | }; | 165 | }; |
165 | 166 | ||
166 | static const struct snd_soc_dapm_route harmony_audio_map[] = { | ||
167 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
168 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
169 | {"Int Spk", NULL, "ROP"}, | ||
170 | {"Int Spk", NULL, "RON"}, | ||
171 | {"Int Spk", NULL, "LOP"}, | ||
172 | {"Int Spk", NULL, "LON"}, | ||
173 | {"Mic Jack", NULL, "MICBIAS"}, | ||
174 | {"IN1L", NULL, "Mic Jack"}, | ||
175 | }; | ||
176 | |||
177 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { | 167 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { |
178 | SOC_DAPM_PIN_SWITCH("Int Spk"), | 168 | SOC_DAPM_PIN_SWITCH("Int Spk"), |
179 | }; | 169 | }; |
@@ -185,10 +175,9 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | |||
185 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 175 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
186 | struct snd_soc_card *card = codec->card; | 176 | struct snd_soc_card *card = codec->card; |
187 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 177 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
188 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
189 | 178 | ||
190 | if (gpio_is_valid(pdata->gpio_hp_det)) { | 179 | if (gpio_is_valid(machine->gpio_hp_det)) { |
191 | tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; | 180 | tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det; |
192 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 181 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
193 | &tegra_wm8903_hp_jack); | 182 | &tegra_wm8903_hp_jack); |
194 | snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, | 183 | snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, |
@@ -226,9 +215,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card) | |||
226 | static struct snd_soc_dai_link tegra_wm8903_dai = { | 215 | static struct snd_soc_dai_link tegra_wm8903_dai = { |
227 | .name = "WM8903", | 216 | .name = "WM8903", |
228 | .stream_name = "WM8903 PCM", | 217 | .stream_name = "WM8903 PCM", |
229 | .codec_name = "wm8903.0-001a", | ||
230 | .platform_name = "tegra20-i2s.0", | ||
231 | .cpu_dai_name = "tegra20-i2s.0", | ||
232 | .codec_dai_name = "wm8903-hifi", | 218 | .codec_dai_name = "wm8903-hifi", |
233 | .init = tegra_wm8903_init, | 219 | .init = tegra_wm8903_init, |
234 | .ops = &tegra_wm8903_ops, | 220 | .ops = &tegra_wm8903_ops, |
@@ -257,96 +243,25 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
257 | struct device_node *np = pdev->dev.of_node; | 243 | struct device_node *np = pdev->dev.of_node; |
258 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; | 244 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; |
259 | struct tegra_wm8903 *machine; | 245 | struct tegra_wm8903 *machine; |
260 | struct tegra_wm8903_platform_data *pdata; | ||
261 | int ret; | 246 | int ret; |
262 | 247 | ||
263 | if (!pdev->dev.platform_data && !pdev->dev.of_node) { | ||
264 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), | 248 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), |
269 | GFP_KERNEL); | 249 | GFP_KERNEL); |
270 | if (!machine) { | 250 | if (!machine) { |
271 | dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); | 251 | dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); |
272 | ret = -ENOMEM; | 252 | return -ENOMEM; |
273 | goto err; | ||
274 | } | 253 | } |
275 | pdata = &machine->pdata; | ||
276 | 254 | ||
277 | card->dev = &pdev->dev; | 255 | card->dev = &pdev->dev; |
278 | platform_set_drvdata(pdev, card); | 256 | platform_set_drvdata(pdev, card); |
279 | snd_soc_card_set_drvdata(card, machine); | 257 | snd_soc_card_set_drvdata(card, machine); |
280 | 258 | ||
281 | if (pdev->dev.platform_data) { | 259 | machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", |
282 | memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); | 260 | 0); |
283 | } else if (np) { | 261 | if (machine->gpio_spkr_en == -EPROBE_DEFER) |
284 | pdata->gpio_spkr_en = of_get_named_gpio(np, | 262 | return -EPROBE_DEFER; |
285 | "nvidia,spkr-en-gpios", 0); | 263 | if (gpio_is_valid(machine->gpio_spkr_en)) { |
286 | if (pdata->gpio_spkr_en == -EPROBE_DEFER) | 264 | ret = devm_gpio_request_one(&pdev->dev, machine->gpio_spkr_en, |
287 | return -EPROBE_DEFER; | ||
288 | |||
289 | pdata->gpio_hp_mute = of_get_named_gpio(np, | ||
290 | "nvidia,hp-mute-gpios", 0); | ||
291 | if (pdata->gpio_hp_mute == -EPROBE_DEFER) | ||
292 | return -EPROBE_DEFER; | ||
293 | |||
294 | pdata->gpio_hp_det = of_get_named_gpio(np, | ||
295 | "nvidia,hp-det-gpios", 0); | ||
296 | if (pdata->gpio_hp_det == -EPROBE_DEFER) | ||
297 | return -EPROBE_DEFER; | ||
298 | |||
299 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | ||
300 | "nvidia,int-mic-en-gpios", 0); | ||
301 | if (pdata->gpio_int_mic_en == -EPROBE_DEFER) | ||
302 | return -EPROBE_DEFER; | ||
303 | |||
304 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | ||
305 | "nvidia,ext-mic-en-gpios", 0); | ||
306 | if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) | ||
307 | return -EPROBE_DEFER; | ||
308 | } | ||
309 | |||
310 | if (np) { | ||
311 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
312 | if (ret) | ||
313 | goto err; | ||
314 | |||
315 | ret = snd_soc_of_parse_audio_routing(card, | ||
316 | "nvidia,audio-routing"); | ||
317 | if (ret) | ||
318 | goto err; | ||
319 | |||
320 | tegra_wm8903_dai.codec_name = NULL; | ||
321 | tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, | ||
322 | "nvidia,audio-codec", 0); | ||
323 | if (!tegra_wm8903_dai.codec_of_node) { | ||
324 | dev_err(&pdev->dev, | ||
325 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
326 | ret = -EINVAL; | ||
327 | goto err; | ||
328 | } | ||
329 | |||
330 | tegra_wm8903_dai.cpu_dai_name = NULL; | ||
331 | tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, | ||
332 | "nvidia,i2s-controller", 0); | ||
333 | if (!tegra_wm8903_dai.cpu_of_node) { | ||
334 | dev_err(&pdev->dev, | ||
335 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
336 | ret = -EINVAL; | ||
337 | goto err; | ||
338 | } | ||
339 | |||
340 | tegra_wm8903_dai.platform_name = NULL; | ||
341 | tegra_wm8903_dai.platform_of_node = | ||
342 | tegra_wm8903_dai.cpu_of_node; | ||
343 | } else { | ||
344 | card->dapm_routes = harmony_audio_map; | ||
345 | card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); | ||
346 | } | ||
347 | |||
348 | if (gpio_is_valid(pdata->gpio_spkr_en)) { | ||
349 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en, | ||
350 | GPIOF_OUT_INIT_LOW, "spkr_en"); | 265 | GPIOF_OUT_INIT_LOW, "spkr_en"); |
351 | if (ret) { | 266 | if (ret) { |
352 | dev_err(card->dev, "cannot get spkr_en gpio\n"); | 267 | dev_err(card->dev, "cannot get spkr_en gpio\n"); |
@@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
354 | } | 269 | } |
355 | } | 270 | } |
356 | 271 | ||
357 | if (gpio_is_valid(pdata->gpio_hp_mute)) { | 272 | machine->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios", |
358 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, | 273 | 0); |
274 | if (machine->gpio_hp_mute == -EPROBE_DEFER) | ||
275 | return -EPROBE_DEFER; | ||
276 | if (gpio_is_valid(machine->gpio_hp_mute)) { | ||
277 | ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_mute, | ||
359 | GPIOF_OUT_INIT_HIGH, "hp_mute"); | 278 | GPIOF_OUT_INIT_HIGH, "hp_mute"); |
360 | if (ret) { | 279 | if (ret) { |
361 | dev_err(card->dev, "cannot get hp_mute gpio\n"); | 280 | dev_err(card->dev, "cannot get hp_mute gpio\n"); |
@@ -363,9 +282,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
363 | } | 282 | } |
364 | } | 283 | } |
365 | 284 | ||
366 | if (gpio_is_valid(pdata->gpio_int_mic_en)) { | 285 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); |
286 | if (machine->gpio_hp_det == -EPROBE_DEFER) | ||
287 | return -EPROBE_DEFER; | ||
288 | |||
289 | machine->gpio_int_mic_en = of_get_named_gpio(np, | ||
290 | "nvidia,int-mic-en-gpios", 0); | ||
291 | if (machine->gpio_int_mic_en == -EPROBE_DEFER) | ||
292 | return -EPROBE_DEFER; | ||
293 | if (gpio_is_valid(machine->gpio_int_mic_en)) { | ||
367 | /* Disable int mic; enable signal is active-high */ | 294 | /* Disable int mic; enable signal is active-high */ |
368 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en, | 295 | ret = devm_gpio_request_one(&pdev->dev, |
296 | machine->gpio_int_mic_en, | ||
369 | GPIOF_OUT_INIT_LOW, "int_mic_en"); | 297 | GPIOF_OUT_INIT_LOW, "int_mic_en"); |
370 | if (ret) { | 298 | if (ret) { |
371 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); | 299 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); |
@@ -373,9 +301,14 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
373 | } | 301 | } |
374 | } | 302 | } |
375 | 303 | ||
376 | if (gpio_is_valid(pdata->gpio_ext_mic_en)) { | 304 | machine->gpio_ext_mic_en = of_get_named_gpio(np, |
305 | "nvidia,ext-mic-en-gpios", 0); | ||
306 | if (machine->gpio_ext_mic_en == -EPROBE_DEFER) | ||
307 | return -EPROBE_DEFER; | ||
308 | if (gpio_is_valid(machine->gpio_ext_mic_en)) { | ||
377 | /* Enable ext mic; enable signal is active-low */ | 309 | /* Enable ext mic; enable signal is active-low */ |
378 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en, | 310 | ret = devm_gpio_request_one(&pdev->dev, |
311 | machine->gpio_ext_mic_en, | ||
379 | GPIOF_OUT_INIT_LOW, "ext_mic_en"); | 312 | GPIOF_OUT_INIT_LOW, "ext_mic_en"); |
380 | if (ret) { | 313 | if (ret) { |
381 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); | 314 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); |
@@ -383,6 +316,34 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
383 | } | 316 | } |
384 | } | 317 | } |
385 | 318 | ||
319 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
320 | if (ret) | ||
321 | goto err; | ||
322 | |||
323 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
324 | if (ret) | ||
325 | goto err; | ||
326 | |||
327 | tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, | ||
328 | "nvidia,audio-codec", 0); | ||
329 | if (!tegra_wm8903_dai.codec_of_node) { | ||
330 | dev_err(&pdev->dev, | ||
331 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
332 | ret = -EINVAL; | ||
333 | goto err; | ||
334 | } | ||
335 | |||
336 | tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, | ||
337 | "nvidia,i2s-controller", 0); | ||
338 | if (!tegra_wm8903_dai.cpu_of_node) { | ||
339 | dev_err(&pdev->dev, | ||
340 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
341 | ret = -EINVAL; | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | tegra_wm8903_dai.platform_of_node = tegra_wm8903_dai.cpu_of_node; | ||
346 | |||
386 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | 347 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); |
387 | if (ret) | 348 | if (ret) |
388 | goto err; | 349 | goto err; |
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 68d42403d9b5..5e119630b0e0 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c | |||
@@ -55,7 +55,7 @@ static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) | |||
55 | static struct snd_soc_dai_link tegra_wm9712_dai = { | 55 | static struct snd_soc_dai_link tegra_wm9712_dai = { |
56 | .name = "AC97 HiFi", | 56 | .name = "AC97 HiFi", |
57 | .stream_name = "AC97 HiFi", | 57 | .stream_name = "AC97 HiFi", |
58 | .cpu_dai_name = "tegra-ac97-pcm", | 58 | .cpu_dai_name = "tegra20-ac97", |
59 | .codec_dai_name = "wm9712-hifi", | 59 | .codec_dai_name = "wm9712-hifi", |
60 | .codec_name = "wm9712-codec", | 60 | .codec_name = "wm9712-codec", |
61 | .init = tegra_wm9712_init, | 61 | .init = tegra_wm9712_init, |
@@ -79,11 +79,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) | |||
79 | struct tegra_wm9712 *machine; | 79 | struct tegra_wm9712 *machine; |
80 | int ret; | 80 | int ret; |
81 | 81 | ||
82 | if (!pdev->dev.of_node) { | ||
83 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712), | 82 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712), |
88 | GFP_KERNEL); | 83 | GFP_KERNEL); |
89 | if (!machine) { | 84 | if (!machine) { |
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 7fcf6c2297db..05c68aab5cf0 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c | |||
@@ -97,9 +97,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = { | |||
97 | static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { | 97 | static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { |
98 | .name = "TLV320AIC23", | 98 | .name = "TLV320AIC23", |
99 | .stream_name = "AIC23", | 99 | .stream_name = "AIC23", |
100 | .codec_name = "tlv320aic23-codec.2-001a", | ||
101 | .platform_name = "tegra20-i2s.0", | ||
102 | .cpu_dai_name = "tegra20-i2s.0", | ||
103 | .codec_dai_name = "tlv320aic23-hifi", | 100 | .codec_dai_name = "tlv320aic23-hifi", |
104 | .ops = &trimslice_asoc_ops, | 101 | .ops = &trimslice_asoc_ops, |
105 | .dai_fmt = SND_SOC_DAIFMT_I2S | | 102 | .dai_fmt = SND_SOC_DAIFMT_I2S | |
@@ -122,6 +119,7 @@ static struct snd_soc_card snd_soc_trimslice = { | |||
122 | 119 | ||
123 | static int tegra_snd_trimslice_probe(struct platform_device *pdev) | 120 | static int tegra_snd_trimslice_probe(struct platform_device *pdev) |
124 | { | 121 | { |
122 | struct device_node *np = pdev->dev.of_node; | ||
125 | struct snd_soc_card *card = &snd_soc_trimslice; | 123 | struct snd_soc_card *card = &snd_soc_trimslice; |
126 | struct tegra_trimslice *trimslice; | 124 | struct tegra_trimslice *trimslice; |
127 | int ret; | 125 | int ret; |
@@ -130,44 +128,38 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) | |||
130 | GFP_KERNEL); | 128 | GFP_KERNEL); |
131 | if (!trimslice) { | 129 | if (!trimslice) { |
132 | dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n"); | 130 | dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n"); |
133 | ret = -ENOMEM; | 131 | return -ENOMEM; |
132 | } | ||
133 | |||
134 | card->dev = &pdev->dev; | ||
135 | platform_set_drvdata(pdev, card); | ||
136 | snd_soc_card_set_drvdata(card, trimslice); | ||
137 | |||
138 | trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(np, | ||
139 | "nvidia,audio-codec", 0); | ||
140 | if (!trimslice_tlv320aic23_dai.codec_of_node) { | ||
141 | dev_err(&pdev->dev, | ||
142 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
143 | ret = -EINVAL; | ||
134 | goto err; | 144 | goto err; |
135 | } | 145 | } |
136 | 146 | ||
137 | if (pdev->dev.of_node) { | 147 | trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(np, |
138 | trimslice_tlv320aic23_dai.codec_name = NULL; | 148 | "nvidia,i2s-controller", 0); |
139 | trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle( | 149 | if (!trimslice_tlv320aic23_dai.cpu_of_node) { |
140 | pdev->dev.of_node, "nvidia,audio-codec", 0); | 150 | dev_err(&pdev->dev, |
141 | if (!trimslice_tlv320aic23_dai.codec_of_node) { | 151 | "Property 'nvidia,i2s-controller' missing or invalid\n"); |
142 | dev_err(&pdev->dev, | 152 | ret = -EINVAL; |
143 | "Property 'nvidia,audio-codec' missing or invalid\n"); | 153 | goto err; |
144 | ret = -EINVAL; | ||
145 | goto err; | ||
146 | } | ||
147 | |||
148 | trimslice_tlv320aic23_dai.cpu_dai_name = NULL; | ||
149 | trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle( | ||
150 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | ||
151 | if (!trimslice_tlv320aic23_dai.cpu_of_node) { | ||
152 | dev_err(&pdev->dev, | ||
153 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
154 | ret = -EINVAL; | ||
155 | goto err; | ||
156 | } | ||
157 | |||
158 | trimslice_tlv320aic23_dai.platform_name = NULL; | ||
159 | trimslice_tlv320aic23_dai.platform_of_node = | ||
160 | trimslice_tlv320aic23_dai.cpu_of_node; | ||
161 | } | 154 | } |
162 | 155 | ||
156 | trimslice_tlv320aic23_dai.platform_of_node = | ||
157 | trimslice_tlv320aic23_dai.cpu_of_node; | ||
158 | |||
163 | ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); | 159 | ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); |
164 | if (ret) | 160 | if (ret) |
165 | goto err; | 161 | goto err; |
166 | 162 | ||
167 | card->dev = &pdev->dev; | ||
168 | platform_set_drvdata(pdev, card); | ||
169 | snd_soc_card_set_drvdata(card, trimslice); | ||
170 | |||
171 | ret = snd_soc_register_card(card); | 163 | ret = snd_soc_register_card(card); |
172 | if (ret) { | 164 | if (ret) { |
173 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | 165 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 16ab69635e2e..8a2840304d28 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c | |||
@@ -170,6 +170,10 @@ static struct snd_soc_dai_driver txx9aclc_ac97_dai = { | |||
170 | }, | 170 | }, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static const struct snd_soc_component_driver txx9aclc_ac97_component = { | ||
174 | .name = "txx9aclc-ac97", | ||
175 | }; | ||
176 | |||
173 | static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) | 177 | static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) |
174 | { | 178 | { |
175 | struct txx9aclc_plat_drvdata *drvdata; | 179 | struct txx9aclc_plat_drvdata *drvdata; |
@@ -205,12 +209,13 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) | |||
205 | if (err < 0) | 209 | if (err < 0) |
206 | return err; | 210 | return err; |
207 | 211 | ||
208 | return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai); | 212 | return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, |
213 | &txx9aclc_ac97_dai, 1); | ||
209 | } | 214 | } |
210 | 215 | ||
211 | static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) | 216 | static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) |
212 | { | 217 | { |
213 | snd_soc_unregister_dai(&pdev->dev); | 218 | snd_soc_unregister_component(&pdev->dev); |
214 | return 0; | 219 | return 0; |
215 | } | 220 | } |
216 | 221 | ||
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig index 6b799c0e88df..aa5011894c74 100644 --- a/sound/soc/ux500/Kconfig +++ b/sound/soc/ux500/Kconfig | |||
@@ -16,7 +16,7 @@ config SND_SOC_UX500_PLAT_MSP_I2S | |||
16 | config SND_SOC_UX500_PLAT_DMA | 16 | config SND_SOC_UX500_PLAT_DMA |
17 | tristate "Platform - DB8500 (DMA)" | 17 | tristate "Platform - DB8500 (DMA)" |
18 | depends on SND_SOC_UX500 | 18 | depends on SND_SOC_UX500 |
19 | select SND_SOC_DMAENGINE_PCM | 19 | select SND_SOC_GENERIC_DMAENGINE_PCM |
20 | help | 20 | help |
21 | Say Y if you want to enable the Ux500 platform-driver. | 21 | Say Y if you want to enable the Ux500 platform-driver. |
22 | 22 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 54028cf76511..7d5fc1328523 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -766,6 +766,11 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { | |||
766 | }, | 766 | }, |
767 | }; | 767 | }; |
768 | 768 | ||
769 | static const struct snd_soc_component_driver ux500_msp_component = { | ||
770 | .name = "ux500-msp", | ||
771 | }; | ||
772 | |||
773 | |||
769 | static int ux500_msp_drv_probe(struct platform_device *pdev) | 774 | static int ux500_msp_drv_probe(struct platform_device *pdev) |
770 | { | 775 | { |
771 | struct ux500_msp_i2s_drvdata *drvdata; | 776 | struct ux500_msp_i2s_drvdata *drvdata; |
@@ -823,8 +828,8 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) | |||
823 | } | 828 | } |
824 | dev_set_drvdata(&pdev->dev, drvdata); | 829 | dev_set_drvdata(&pdev->dev, drvdata); |
825 | 830 | ||
826 | ret = snd_soc_register_dai(&pdev->dev, | 831 | ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, |
827 | &ux500_msp_dai_drv[drvdata->msp->id]); | 832 | &ux500_msp_dai_drv[drvdata->msp->id], 1); |
828 | if (ret < 0) { | 833 | if (ret < 0) { |
829 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", | 834 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", |
830 | __func__, drvdata->msp->id); | 835 | __func__, drvdata->msp->id); |
@@ -842,7 +847,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) | |||
842 | return 0; | 847 | return 0; |
843 | 848 | ||
844 | err_reg_plat: | 849 | err_reg_plat: |
845 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 850 | snd_soc_unregister_component(&pdev->dev); |
846 | err_init_msp: | 851 | err_init_msp: |
847 | clk_put(drvdata->clk); | 852 | clk_put(drvdata->clk); |
848 | err_clk: | 853 | err_clk: |
@@ -859,7 +864,7 @@ static int ux500_msp_drv_remove(struct platform_device *pdev) | |||
859 | 864 | ||
860 | ux500_pcm_unregister_platform(pdev); | 865 | ux500_pcm_unregister_platform(pdev); |
861 | 866 | ||
862 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); | 867 | snd_soc_unregister_component(&pdev->dev); |
863 | 868 | ||
864 | devm_regulator_put(drvdata->reg_vape); | 869 | devm_regulator_put(drvdata->reg_vape); |
865 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); | 870 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); |
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index 9c778d9c3838..f53104359f15 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h | |||
@@ -35,13 +35,8 @@ | |||
35 | #define FRAME_PER_8_SLOTS 138 | 35 | #define FRAME_PER_8_SLOTS 138 |
36 | #define FRAME_PER_16_SLOTS 277 | 36 | #define FRAME_PER_16_SLOTS 277 |
37 | 37 | ||
38 | #ifndef CONFIG_SND_SOC_UX500_AB5500 | ||
39 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000 | 38 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000 |
40 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ | 39 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ |
41 | #else | ||
42 | #define UX500_MSP_INTERNAL_CLOCK_FREQ 13000000 | ||
43 | #define UX500_MSP1_INTERNAL_CLOCK_FREQ (UX500_MSP_INTERNAL_CLOCK_FREQ * 2) | ||
44 | #endif | ||
45 | 40 | ||
46 | #define UX500_MSP_MIN_CHANNELS 1 | 41 | #define UX500_MSP_MIN_CHANNELS 1 |
47 | #define UX500_MSP_MAX_CHANNELS 8 | 42 | #define UX500_MSP_MAX_CHANNELS 8 |
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 437f0c032c58..e5cd105c90f9 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -541,6 +541,7 @@ struct ux500_msp_dma_params { | |||
541 | struct stedma40_chan_cfg *dma_cfg; | 541 | struct stedma40_chan_cfg *dma_cfg; |
542 | }; | 542 | }; |
543 | 543 | ||
544 | struct msp_i2s_platform_data; | ||
544 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, | 545 | int ux500_msp_i2s_init_msp(struct platform_device *pdev, |
545 | struct ux500_msp **msp_p, | 546 | struct ux500_msp **msp_p, |
546 | struct msp_i2s_platform_data *platform_data); | 547 | struct msp_i2s_platform_data *platform_data); |
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 846fa82a58d0..b6e5ae277299 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -28,28 +28,19 @@ | |||
28 | #include "ux500_msp_i2s.h" | 28 | #include "ux500_msp_i2s.h" |
29 | #include "ux500_pcm.h" | 29 | #include "ux500_pcm.h" |
30 | 30 | ||
31 | static struct snd_pcm_hardware ux500_pcm_hw_playback = { | 31 | #define UX500_PLATFORM_MIN_RATE 8000 |
32 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 32 | #define UX500_PLATFORM_MAX_RATE 48000 |
33 | SNDRV_PCM_INFO_MMAP | | 33 | |
34 | SNDRV_PCM_INFO_RESUME | | 34 | #define UX500_PLATFORM_MIN_CHANNELS 1 |
35 | SNDRV_PCM_INFO_PAUSE, | 35 | #define UX500_PLATFORM_MAX_CHANNELS 8 |
36 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
37 | SNDRV_PCM_FMTBIT_U16_LE | | ||
38 | SNDRV_PCM_FMTBIT_S16_BE | | ||
39 | SNDRV_PCM_FMTBIT_U16_BE, | ||
40 | .rates = SNDRV_PCM_RATE_KNOT, | ||
41 | .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK, | ||
42 | .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK, | ||
43 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | ||
44 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | ||
45 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | ||
46 | .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, | ||
47 | .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, | ||
48 | .periods_min = UX500_PLATFORM_PERIODS_MIN, | ||
49 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | ||
50 | }; | ||
51 | 36 | ||
52 | static struct snd_pcm_hardware ux500_pcm_hw_capture = { | 37 | #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 |
38 | #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) | ||
39 | #define UX500_PLATFORM_PERIODS_MIN 2 | ||
40 | #define UX500_PLATFORM_PERIODS_MAX 48 | ||
41 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | ||
42 | |||
43 | static const struct snd_pcm_hardware ux500_pcm_hw = { | ||
53 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 44 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
54 | SNDRV_PCM_INFO_MMAP | | 45 | SNDRV_PCM_INFO_MMAP | |
55 | SNDRV_PCM_INFO_RESUME | | 46 | SNDRV_PCM_INFO_RESUME | |
@@ -59,8 +50,8 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = { | |||
59 | SNDRV_PCM_FMTBIT_S16_BE | | 50 | SNDRV_PCM_FMTBIT_S16_BE | |
60 | SNDRV_PCM_FMTBIT_U16_BE, | 51 | SNDRV_PCM_FMTBIT_U16_BE, |
61 | .rates = SNDRV_PCM_RATE_KNOT, | 52 | .rates = SNDRV_PCM_RATE_KNOT, |
62 | .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, | 53 | .rate_min = UX500_PLATFORM_MIN_RATE, |
63 | .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, | 54 | .rate_max = UX500_PLATFORM_MAX_RATE, |
64 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, | 55 | .channels_min = UX500_PLATFORM_MIN_CHANNELS, |
65 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, | 56 | .channels_max = UX500_PLATFORM_MAX_CHANNELS, |
66 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, | 57 | .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, |
@@ -70,64 +61,23 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = { | |||
70 | .periods_max = UX500_PLATFORM_PERIODS_MAX, | 61 | .periods_max = UX500_PLATFORM_PERIODS_MAX, |
71 | }; | 62 | }; |
72 | 63 | ||
73 | static void ux500_pcm_dma_hw_free(struct device *dev, | 64 | static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, |
74 | struct snd_pcm_substream *substream) | 65 | struct snd_pcm_substream *substream) |
75 | { | 66 | { |
76 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
77 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
78 | |||
79 | if (runtime->dma_area == NULL) | ||
80 | return; | ||
81 | |||
82 | if (buf != &substream->dma_buffer) { | ||
83 | dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, | ||
84 | buf->addr); | ||
85 | kfree(runtime->dma_buffer_p); | ||
86 | } | ||
87 | |||
88 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
89 | } | ||
90 | |||
91 | static int ux500_pcm_open(struct snd_pcm_substream *substream) | ||
92 | { | ||
93 | int stream_id = substream->pstr->stream; | ||
94 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
96 | struct snd_soc_dai *dai = rtd->cpu_dai; | 67 | struct snd_soc_dai *dai = rtd->cpu_dai; |
97 | struct device *dev = dai->dev; | 68 | struct device *dev = dai->dev; |
98 | int ret; | ||
99 | struct ux500_msp_dma_params *dma_params; | ||
100 | u16 per_data_width, mem_data_width; | 69 | u16 per_data_width, mem_data_width; |
101 | struct stedma40_chan_cfg *dma_cfg; | 70 | struct stedma40_chan_cfg *dma_cfg; |
71 | struct ux500_msp_dma_params *dma_params; | ||
102 | 72 | ||
103 | dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, | 73 | dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, |
104 | snd_pcm_stream_str(substream)); | 74 | snd_pcm_stream_str(substream)); |
105 | 75 | ||
106 | dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); | 76 | dma_params = snd_soc_dai_get_dma_data(dai, substream); |
107 | if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) | 77 | dma_cfg = dma_params->dma_cfg; |
108 | snd_soc_set_runtime_hwparams(substream, | ||
109 | &ux500_pcm_hw_playback); | ||
110 | else | ||
111 | snd_soc_set_runtime_hwparams(substream, | ||
112 | &ux500_pcm_hw_capture); | ||
113 | |||
114 | /* ensure that buffer size is a multiple of period size */ | ||
115 | ret = snd_pcm_hw_constraint_integer(runtime, | ||
116 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
117 | if (ret < 0) { | ||
118 | dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", | ||
119 | __func__, ret); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, | ||
124 | snd_pcm_stream_str(substream)); | ||
125 | runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
126 | ux500_pcm_hw_playback : ux500_pcm_hw_capture; | ||
127 | 78 | ||
128 | mem_data_width = STEDMA40_HALFWORD_WIDTH; | 79 | mem_data_width = STEDMA40_HALFWORD_WIDTH; |
129 | 80 | ||
130 | dma_params = snd_soc_dai_get_dma_data(dai, substream); | ||
131 | switch (dma_params->data_size) { | 81 | switch (dma_params->data_size) { |
132 | case 32: | 82 | case 32: |
133 | per_data_width = STEDMA40_WORD_WIDTH; | 83 | per_data_width = STEDMA40_WORD_WIDTH; |
@@ -140,13 +90,8 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) | |||
140 | break; | 90 | break; |
141 | default: | 91 | default: |
142 | per_data_width = STEDMA40_WORD_WIDTH; | 92 | per_data_width = STEDMA40_WORD_WIDTH; |
143 | dev_warn(rtd->platform->dev, | ||
144 | "%s: Unknown data-size (%d)! Assuming 32 bits.\n", | ||
145 | __func__, dma_params->data_size); | ||
146 | } | 93 | } |
147 | 94 | ||
148 | dma_cfg = dma_params->dma_cfg; | ||
149 | |||
150 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 95 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
151 | dma_cfg->src_info.data_width = mem_data_width; | 96 | dma_cfg->src_info.data_width = mem_data_width; |
152 | dma_cfg->dst_info.data_width = per_data_width; | 97 | dma_cfg->dst_info.data_width = per_data_width; |
@@ -155,137 +100,24 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) | |||
155 | dma_cfg->dst_info.data_width = mem_data_width; | 100 | dma_cfg->dst_info.data_width = mem_data_width; |
156 | } | 101 | } |
157 | 102 | ||
158 | 103 | return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg); | |
159 | ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg); | ||
160 | if (ret) { | ||
161 | dev_dbg(dai->dev, | ||
162 | "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n", | ||
163 | __func__, ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | snd_dmaengine_pcm_set_data(substream, dma_cfg); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int ux500_pcm_close(struct snd_pcm_substream *substream) | ||
173 | { | ||
174 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
175 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
176 | |||
177 | dev_dbg(dai->dev, "%s: Enter\n", __func__); | ||
178 | |||
179 | snd_dmaengine_pcm_close(substream); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, | ||
185 | struct snd_pcm_hw_params *hw_params) | ||
186 | { | ||
187 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
188 | struct snd_dma_buffer *buf = runtime->dma_buffer_p; | ||
189 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
190 | int ret = 0; | ||
191 | int size; | ||
192 | |||
193 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
194 | |||
195 | size = params_buffer_bytes(hw_params); | ||
196 | |||
197 | if (buf) { | ||
198 | if (buf->bytes >= size) | ||
199 | goto out; | ||
200 | ux500_pcm_dma_hw_free(NULL, substream); | ||
201 | } | ||
202 | |||
203 | if (substream->dma_buffer.area != NULL && | ||
204 | substream->dma_buffer.bytes >= size) { | ||
205 | buf = &substream->dma_buffer; | ||
206 | } else { | ||
207 | buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); | ||
208 | if (!buf) | ||
209 | goto nomem; | ||
210 | |||
211 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
212 | buf->dev.dev = NULL; | ||
213 | buf->area = dma_alloc_coherent(NULL, size, &buf->addr, | ||
214 | GFP_KERNEL); | ||
215 | buf->bytes = size; | ||
216 | buf->private_data = NULL; | ||
217 | |||
218 | if (!buf->area) | ||
219 | goto free; | ||
220 | } | ||
221 | snd_pcm_set_runtime_buffer(substream, buf); | ||
222 | ret = 1; | ||
223 | out: | ||
224 | runtime->dma_bytes = size; | ||
225 | return ret; | ||
226 | |||
227 | free: | ||
228 | kfree(buf); | ||
229 | nomem: | ||
230 | return -ENOMEM; | ||
231 | } | 104 | } |
232 | 105 | ||
233 | static int ux500_pcm_hw_free(struct snd_pcm_substream *substream) | 106 | static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { |
234 | { | 107 | .pcm_hardware = &ux500_pcm_hw, |
235 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 108 | .compat_request_channel = ux500_pcm_request_chan, |
236 | 109 | .prealloc_buffer_size = 128 * 1024, | |
237 | dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__); | ||
238 | |||
239 | ux500_pcm_dma_hw_free(NULL, substream); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int ux500_pcm_mmap(struct snd_pcm_substream *substream, | ||
245 | struct vm_area_struct *vma) | ||
246 | { | ||
247 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
248 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
249 | |||
250 | dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__); | ||
251 | |||
252 | return dma_mmap_coherent(NULL, vma, runtime->dma_area, | ||
253 | runtime->dma_addr, runtime->dma_bytes); | ||
254 | } | ||
255 | |||
256 | static struct snd_pcm_ops ux500_pcm_ops = { | ||
257 | .open = ux500_pcm_open, | ||
258 | .close = ux500_pcm_close, | ||
259 | .ioctl = snd_pcm_lib_ioctl, | ||
260 | .hw_params = ux500_pcm_hw_params, | ||
261 | .hw_free = ux500_pcm_hw_free, | ||
262 | .trigger = snd_dmaengine_pcm_trigger, | ||
263 | .pointer = snd_dmaengine_pcm_pointer_no_residue, | ||
264 | .mmap = ux500_pcm_mmap | ||
265 | }; | ||
266 | |||
267 | int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
268 | { | ||
269 | struct snd_pcm *pcm = rtd->pcm; | ||
270 | |||
271 | dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__, | ||
272 | pcm->id); | ||
273 | |||
274 | pcm->info_flags = 0; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static struct snd_soc_platform_driver ux500_pcm_soc_drv = { | ||
280 | .ops = &ux500_pcm_ops, | ||
281 | .pcm_new = ux500_pcm_new, | ||
282 | }; | 110 | }; |
283 | 111 | ||
284 | int ux500_pcm_register_platform(struct platform_device *pdev) | 112 | int ux500_pcm_register_platform(struct platform_device *pdev) |
285 | { | 113 | { |
286 | int ret; | 114 | int ret; |
287 | 115 | ||
288 | ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv); | 116 | ret = snd_dmaengine_pcm_register(&pdev->dev, |
117 | &ux500_dmaengine_pcm_config, | ||
118 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | | ||
119 | SND_DMAENGINE_PCM_FLAG_COMPAT | | ||
120 | SND_DMAENGINE_PCM_FLAG_NO_DT); | ||
289 | if (ret < 0) { | 121 | if (ret < 0) { |
290 | dev_err(&pdev->dev, | 122 | dev_err(&pdev->dev, |
291 | "%s: ERROR: Failed to register platform '%s' (%d)!\n", | 123 | "%s: ERROR: Failed to register platform '%s' (%d)!\n", |
@@ -299,8 +131,7 @@ EXPORT_SYMBOL_GPL(ux500_pcm_register_platform); | |||
299 | 131 | ||
300 | int ux500_pcm_unregister_platform(struct platform_device *pdev) | 132 | int ux500_pcm_unregister_platform(struct platform_device *pdev) |
301 | { | 133 | { |
302 | snd_soc_unregister_platform(&pdev->dev); | 134 | snd_dmaengine_pcm_unregister(&pdev->dev); |
303 | |||
304 | return 0; | 135 | return 0; |
305 | } | 136 | } |
306 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); | 137 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); |
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index 76d344476afc..d76e1aff6458 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h | |||
@@ -18,20 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | 20 | ||
21 | #define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000 | ||
22 | #define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000 | ||
23 | #define UX500_PLATFORM_MIN_RATE_CAPTURE 8000 | ||
24 | #define UX500_PLATFORM_MAX_RATE_CAPTURE 48000 | ||
25 | |||
26 | #define UX500_PLATFORM_MIN_CHANNELS 1 | ||
27 | #define UX500_PLATFORM_MAX_CHANNELS 8 | ||
28 | |||
29 | #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 | ||
30 | #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) | ||
31 | #define UX500_PLATFORM_PERIODS_MIN 2 | ||
32 | #define UX500_PLATFORM_PERIODS_MAX 48 | ||
33 | #define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE) | ||
34 | |||
35 | int ux500_pcm_register_platform(struct platform_device *pdev); | 21 | int ux500_pcm_register_platform(struct platform_device *pdev); |
36 | int ux500_pcm_unregister_platform(struct platform_device *pdev); | 22 | int ux500_pcm_unregister_platform(struct platform_device *pdev); |
37 | 23 | ||
diff --git a/sound/sound_core.c b/sound/sound_core.c index bb23009edc8d..359753fc24e1 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c | |||
@@ -352,7 +352,9 @@ static struct sound_unit *chains[SOUND_STEP]; | |||
352 | * @dev: device pointer | 352 | * @dev: device pointer |
353 | * | 353 | * |
354 | * Allocate a special sound device by minor number from the sound | 354 | * Allocate a special sound device by minor number from the sound |
355 | * subsystem. The allocated number is returned on success. On failure | 355 | * subsystem. |
356 | * | ||
357 | * Return: The allocated number is returned on success. On failure, | ||
356 | * a negative error code is returned. | 358 | * a negative error code is returned. |
357 | */ | 359 | */ |
358 | 360 | ||
@@ -436,8 +438,10 @@ EXPORT_SYMBOL(register_sound_special); | |||
436 | * @dev: Unit number to allocate | 438 | * @dev: Unit number to allocate |
437 | * | 439 | * |
438 | * Allocate a mixer device. Unit is the number of the mixer requested. | 440 | * Allocate a mixer device. Unit is the number of the mixer requested. |
439 | * Pass -1 to request the next free mixer unit. On success the allocated | 441 | * Pass -1 to request the next free mixer unit. |
440 | * number is returned, on failure a negative error code is returned. | 442 | * |
443 | * Return: On success, the allocated number is returned. On failure, | ||
444 | * a negative error code is returned. | ||
441 | */ | 445 | */ |
442 | 446 | ||
443 | int register_sound_mixer(const struct file_operations *fops, int dev) | 447 | int register_sound_mixer(const struct file_operations *fops, int dev) |
@@ -454,8 +458,10 @@ EXPORT_SYMBOL(register_sound_mixer); | |||
454 | * @dev: Unit number to allocate | 458 | * @dev: Unit number to allocate |
455 | * | 459 | * |
456 | * Allocate a midi device. Unit is the number of the midi device requested. | 460 | * Allocate a midi device. Unit is the number of the midi device requested. |
457 | * Pass -1 to request the next free midi unit. On success the allocated | 461 | * Pass -1 to request the next free midi unit. |
458 | * number is returned, on failure a negative error code is returned. | 462 | * |
463 | * Return: On success, the allocated number is returned. On failure, | ||
464 | * a negative error code is returned. | ||
459 | */ | 465 | */ |
460 | 466 | ||
461 | int register_sound_midi(const struct file_operations *fops, int dev) | 467 | int register_sound_midi(const struct file_operations *fops, int dev) |
@@ -477,11 +483,13 @@ EXPORT_SYMBOL(register_sound_midi); | |||
477 | * @dev: Unit number to allocate | 483 | * @dev: Unit number to allocate |
478 | * | 484 | * |
479 | * Allocate a DSP device. Unit is the number of the DSP requested. | 485 | * Allocate a DSP device. Unit is the number of the DSP requested. |
480 | * Pass -1 to request the next free DSP unit. On success the allocated | 486 | * Pass -1 to request the next free DSP unit. |
481 | * number is returned, on failure a negative error code is returned. | ||
482 | * | 487 | * |
483 | * This function allocates both the audio and dsp device entries together | 488 | * This function allocates both the audio and dsp device entries together |
484 | * and will always allocate them as a matching pair - eg dsp3/audio3 | 489 | * and will always allocate them as a matching pair - eg dsp3/audio3 |
490 | * | ||
491 | * Return: On success, the allocated number is returned. On failure, | ||
492 | * a negative error code is returned. | ||
485 | */ | 493 | */ |
486 | 494 | ||
487 | int register_sound_dsp(const struct file_operations *fops, int dev) | 495 | int register_sound_dsp(const struct file_operations *fops, int dev) |
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 4dd60d8a4889..a1a24b979ed2 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c | |||
@@ -1075,10 +1075,11 @@ out: | |||
1075 | return 0; | 1075 | return 0; |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | #ifdef CONFIG_PM | 1078 | #ifdef CONFIG_PM_SLEEP |
1079 | static int snd_at73c213_suspend(struct spi_device *spi, pm_message_t msg) | 1079 | |
1080 | static int snd_at73c213_suspend(struct device *dev) | ||
1080 | { | 1081 | { |
1081 | struct snd_card *card = dev_get_drvdata(&spi->dev); | 1082 | struct snd_card *card = dev_get_drvdata(dev); |
1082 | struct snd_at73c213 *chip = card->private_data; | 1083 | struct snd_at73c213 *chip = card->private_data; |
1083 | 1084 | ||
1084 | ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); | 1085 | ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS)); |
@@ -1087,9 +1088,9 @@ static int snd_at73c213_suspend(struct spi_device *spi, pm_message_t msg) | |||
1087 | return 0; | 1088 | return 0; |
1088 | } | 1089 | } |
1089 | 1090 | ||
1090 | static int snd_at73c213_resume(struct spi_device *spi) | 1091 | static int snd_at73c213_resume(struct device *dev) |
1091 | { | 1092 | { |
1092 | struct snd_card *card = dev_get_drvdata(&spi->dev); | 1093 | struct snd_card *card = dev_get_drvdata(dev); |
1093 | struct snd_at73c213 *chip = card->private_data; | 1094 | struct snd_at73c213 *chip = card->private_data; |
1094 | 1095 | ||
1095 | clk_enable(chip->board->dac_clk); | 1096 | clk_enable(chip->board->dac_clk); |
@@ -1097,18 +1098,21 @@ static int snd_at73c213_resume(struct spi_device *spi) | |||
1097 | 1098 | ||
1098 | return 0; | 1099 | return 0; |
1099 | } | 1100 | } |
1101 | |||
1102 | static SIMPLE_DEV_PM_OPS(at73c213_pm_ops, snd_at73c213_suspend, | ||
1103 | snd_at73c213_resume); | ||
1104 | #define AT73C213_PM_OPS (&at73c213_pm_ops) | ||
1105 | |||
1100 | #else | 1106 | #else |
1101 | #define snd_at73c213_suspend NULL | 1107 | #define AT73C213_PM_OPS NULL |
1102 | #define snd_at73c213_resume NULL | ||
1103 | #endif | 1108 | #endif |
1104 | 1109 | ||
1105 | static struct spi_driver at73c213_driver = { | 1110 | static struct spi_driver at73c213_driver = { |
1106 | .driver = { | 1111 | .driver = { |
1107 | .name = "at73c213", | 1112 | .name = "at73c213", |
1113 | .pm = AT73C213_PM_OPS, | ||
1108 | }, | 1114 | }, |
1109 | .probe = snd_at73c213_probe, | 1115 | .probe = snd_at73c213_probe, |
1110 | .suspend = snd_at73c213_suspend, | ||
1111 | .resume = snd_at73c213_resume, | ||
1112 | .remove = snd_at73c213_remove, | 1116 | .remove = snd_at73c213_remove, |
1113 | }; | 1117 | }; |
1114 | 1118 | ||
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index e2ca12fe92e9..40dd50a80f55 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -575,7 +575,6 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, | |||
575 | urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep) | 575 | urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep) |
576 | : usb_sndisocpipe(chip->dev, ep); | 576 | : usb_sndisocpipe(chip->dev, ep); |
577 | urb->instance.interval = 1; | 577 | urb->instance.interval = 1; |
578 | urb->instance.transfer_flags = URB_ISO_ASAP; | ||
579 | urb->instance.complete = handler; | 578 | urb->instance.complete = handler; |
580 | urb->instance.context = urb; | 579 | urb->instance.context = urb; |
581 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; | 580 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; |
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index fde9a7a29cb6..c1916184e2e1 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | ||
19 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
@@ -39,8 +40,8 @@ | |||
39 | #define ENDPOINT_CAPTURE 2 | 40 | #define ENDPOINT_CAPTURE 2 |
40 | #define ENDPOINT_PLAYBACK 6 | 41 | #define ENDPOINT_PLAYBACK 6 |
41 | 42 | ||
42 | #define MAKE_CHECKBYTE(dev,stream,i) \ | 43 | #define MAKE_CHECKBYTE(cdev,stream,i) \ |
43 | (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) | 44 | (stream << 1) | (~(i / (cdev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) |
44 | 45 | ||
45 | static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { | 46 | static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { |
46 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 47 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
@@ -60,32 +61,32 @@ static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { | |||
60 | }; | 61 | }; |
61 | 62 | ||
62 | static void | 63 | static void |
63 | activate_substream(struct snd_usb_caiaqdev *dev, | 64 | activate_substream(struct snd_usb_caiaqdev *cdev, |
64 | struct snd_pcm_substream *sub) | 65 | struct snd_pcm_substream *sub) |
65 | { | 66 | { |
66 | spin_lock(&dev->spinlock); | 67 | spin_lock(&cdev->spinlock); |
67 | 68 | ||
68 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 69 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
69 | dev->sub_playback[sub->number] = sub; | 70 | cdev->sub_playback[sub->number] = sub; |
70 | else | 71 | else |
71 | dev->sub_capture[sub->number] = sub; | 72 | cdev->sub_capture[sub->number] = sub; |
72 | 73 | ||
73 | spin_unlock(&dev->spinlock); | 74 | spin_unlock(&cdev->spinlock); |
74 | } | 75 | } |
75 | 76 | ||
76 | static void | 77 | static void |
77 | deactivate_substream(struct snd_usb_caiaqdev *dev, | 78 | deactivate_substream(struct snd_usb_caiaqdev *cdev, |
78 | struct snd_pcm_substream *sub) | 79 | struct snd_pcm_substream *sub) |
79 | { | 80 | { |
80 | unsigned long flags; | 81 | unsigned long flags; |
81 | spin_lock_irqsave(&dev->spinlock, flags); | 82 | spin_lock_irqsave(&cdev->spinlock, flags); |
82 | 83 | ||
83 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 84 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
84 | dev->sub_playback[sub->number] = NULL; | 85 | cdev->sub_playback[sub->number] = NULL; |
85 | else | 86 | else |
86 | dev->sub_capture[sub->number] = NULL; | 87 | cdev->sub_capture[sub->number] = NULL; |
87 | 88 | ||
88 | spin_unlock_irqrestore(&dev->spinlock, flags); | 89 | spin_unlock_irqrestore(&cdev->spinlock, flags); |
89 | } | 90 | } |
90 | 91 | ||
91 | static int | 92 | static int |
@@ -98,28 +99,30 @@ all_substreams_zero(struct snd_pcm_substream **subs) | |||
98 | return 1; | 99 | return 1; |
99 | } | 100 | } |
100 | 101 | ||
101 | static int stream_start(struct snd_usb_caiaqdev *dev) | 102 | static int stream_start(struct snd_usb_caiaqdev *cdev) |
102 | { | 103 | { |
103 | int i, ret; | 104 | int i, ret; |
105 | struct device *dev = caiaqdev_to_dev(cdev); | ||
104 | 106 | ||
105 | debug("%s(%p)\n", __func__, dev); | 107 | dev_dbg(dev, "%s(%p)\n", __func__, cdev); |
106 | 108 | ||
107 | if (dev->streaming) | 109 | if (cdev->streaming) |
108 | return -EINVAL; | 110 | return -EINVAL; |
109 | 111 | ||
110 | memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); | 112 | memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); |
111 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); | 113 | memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); |
112 | dev->input_panic = 0; | 114 | cdev->input_panic = 0; |
113 | dev->output_panic = 0; | 115 | cdev->output_panic = 0; |
114 | dev->first_packet = 4; | 116 | cdev->first_packet = 4; |
115 | dev->streaming = 1; | 117 | cdev->streaming = 1; |
116 | dev->warned = 0; | 118 | cdev->warned = 0; |
117 | 119 | ||
118 | for (i = 0; i < N_URBS; i++) { | 120 | for (i = 0; i < N_URBS; i++) { |
119 | ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); | 121 | ret = usb_submit_urb(cdev->data_urbs_in[i], GFP_ATOMIC); |
120 | if (ret) { | 122 | if (ret) { |
121 | log("unable to trigger read #%d! (ret %d)\n", i, ret); | 123 | dev_err(dev, "unable to trigger read #%d! (ret %d)\n", |
122 | dev->streaming = 0; | 124 | i, ret); |
125 | cdev->streaming = 0; | ||
123 | return -EPIPE; | 126 | return -EPIPE; |
124 | } | 127 | } |
125 | } | 128 | } |
@@ -127,46 +130,51 @@ static int stream_start(struct snd_usb_caiaqdev *dev) | |||
127 | return 0; | 130 | return 0; |
128 | } | 131 | } |
129 | 132 | ||
130 | static void stream_stop(struct snd_usb_caiaqdev *dev) | 133 | static void stream_stop(struct snd_usb_caiaqdev *cdev) |
131 | { | 134 | { |
132 | int i; | 135 | int i; |
136 | struct device *dev = caiaqdev_to_dev(cdev); | ||
133 | 137 | ||
134 | debug("%s(%p)\n", __func__, dev); | 138 | dev_dbg(dev, "%s(%p)\n", __func__, cdev); |
135 | if (!dev->streaming) | 139 | if (!cdev->streaming) |
136 | return; | 140 | return; |
137 | 141 | ||
138 | dev->streaming = 0; | 142 | cdev->streaming = 0; |
139 | 143 | ||
140 | for (i = 0; i < N_URBS; i++) { | 144 | for (i = 0; i < N_URBS; i++) { |
141 | usb_kill_urb(dev->data_urbs_in[i]); | 145 | usb_kill_urb(cdev->data_urbs_in[i]); |
142 | 146 | ||
143 | if (test_bit(i, &dev->outurb_active_mask)) | 147 | if (test_bit(i, &cdev->outurb_active_mask)) |
144 | usb_kill_urb(dev->data_urbs_out[i]); | 148 | usb_kill_urb(cdev->data_urbs_out[i]); |
145 | } | 149 | } |
146 | 150 | ||
147 | dev->outurb_active_mask = 0; | 151 | cdev->outurb_active_mask = 0; |
148 | } | 152 | } |
149 | 153 | ||
150 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) | 154 | static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) |
151 | { | 155 | { |
152 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | 156 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
153 | debug("%s(%p)\n", __func__, substream); | 157 | struct device *dev = caiaqdev_to_dev(cdev); |
154 | substream->runtime->hw = dev->pcm_info; | 158 | |
159 | dev_dbg(dev, "%s(%p)\n", __func__, substream); | ||
160 | substream->runtime->hw = cdev->pcm_info; | ||
155 | snd_pcm_limit_hw_rates(substream->runtime); | 161 | snd_pcm_limit_hw_rates(substream->runtime); |
162 | |||
156 | return 0; | 163 | return 0; |
157 | } | 164 | } |
158 | 165 | ||
159 | static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) | 166 | static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) |
160 | { | 167 | { |
161 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | 168 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
169 | struct device *dev = caiaqdev_to_dev(cdev); | ||
162 | 170 | ||
163 | debug("%s(%p)\n", __func__, substream); | 171 | dev_dbg(dev, "%s(%p)\n", __func__, substream); |
164 | if (all_substreams_zero(dev->sub_playback) && | 172 | if (all_substreams_zero(cdev->sub_playback) && |
165 | all_substreams_zero(dev->sub_capture)) { | 173 | all_substreams_zero(cdev->sub_capture)) { |
166 | /* when the last client has stopped streaming, | 174 | /* when the last client has stopped streaming, |
167 | * all sample rates are allowed again */ | 175 | * all sample rates are allowed again */ |
168 | stream_stop(dev); | 176 | stream_stop(cdev); |
169 | dev->pcm_info.rates = dev->samplerates; | 177 | cdev->pcm_info.rates = cdev->samplerates; |
170 | } | 178 | } |
171 | 179 | ||
172 | return 0; | 180 | return 0; |
@@ -175,15 +183,13 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) | |||
175 | static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, | 183 | static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, |
176 | struct snd_pcm_hw_params *hw_params) | 184 | struct snd_pcm_hw_params *hw_params) |
177 | { | 185 | { |
178 | debug("%s(%p)\n", __func__, sub); | ||
179 | return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); | 186 | return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); |
180 | } | 187 | } |
181 | 188 | ||
182 | static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) | 189 | static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) |
183 | { | 190 | { |
184 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | 191 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
185 | debug("%s(%p)\n", __func__, sub); | 192 | deactivate_substream(cdev, sub); |
186 | deactivate_substream(dev, sub); | ||
187 | return snd_pcm_lib_free_pages(sub); | 193 | return snd_pcm_lib_free_pages(sub); |
188 | } | 194 | } |
189 | 195 | ||
@@ -199,15 +205,16 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
199 | { | 205 | { |
200 | int bytes_per_sample, bpp, ret, i; | 206 | int bytes_per_sample, bpp, ret, i; |
201 | int index = substream->number; | 207 | int index = substream->number; |
202 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); | 208 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(substream); |
203 | struct snd_pcm_runtime *runtime = substream->runtime; | 209 | struct snd_pcm_runtime *runtime = substream->runtime; |
210 | struct device *dev = caiaqdev_to_dev(cdev); | ||
204 | 211 | ||
205 | debug("%s(%p)\n", __func__, substream); | 212 | dev_dbg(dev, "%s(%p)\n", __func__, substream); |
206 | 213 | ||
207 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 214 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
208 | int out_pos; | 215 | int out_pos; |
209 | 216 | ||
210 | switch (dev->spec.data_alignment) { | 217 | switch (cdev->spec.data_alignment) { |
211 | case 0: | 218 | case 0: |
212 | case 2: | 219 | case 2: |
213 | out_pos = BYTES_PER_SAMPLE + 1; | 220 | out_pos = BYTES_PER_SAMPLE + 1; |
@@ -218,12 +225,12 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
218 | break; | 225 | break; |
219 | } | 226 | } |
220 | 227 | ||
221 | dev->period_out_count[index] = out_pos; | 228 | cdev->period_out_count[index] = out_pos; |
222 | dev->audio_out_buf_pos[index] = out_pos; | 229 | cdev->audio_out_buf_pos[index] = out_pos; |
223 | } else { | 230 | } else { |
224 | int in_pos; | 231 | int in_pos; |
225 | 232 | ||
226 | switch (dev->spec.data_alignment) { | 233 | switch (cdev->spec.data_alignment) { |
227 | case 0: | 234 | case 0: |
228 | in_pos = BYTES_PER_SAMPLE + 2; | 235 | in_pos = BYTES_PER_SAMPLE + 2; |
229 | break; | 236 | break; |
@@ -236,44 +243,44 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
236 | break; | 243 | break; |
237 | } | 244 | } |
238 | 245 | ||
239 | dev->period_in_count[index] = in_pos; | 246 | cdev->period_in_count[index] = in_pos; |
240 | dev->audio_in_buf_pos[index] = in_pos; | 247 | cdev->audio_in_buf_pos[index] = in_pos; |
241 | } | 248 | } |
242 | 249 | ||
243 | if (dev->streaming) | 250 | if (cdev->streaming) |
244 | return 0; | 251 | return 0; |
245 | 252 | ||
246 | /* the first client that opens a stream defines the sample rate | 253 | /* the first client that opens a stream defines the sample rate |
247 | * setting for all subsequent calls, until the last client closed. */ | 254 | * setting for all subsequent calls, until the last client closed. */ |
248 | for (i=0; i < ARRAY_SIZE(rates); i++) | 255 | for (i=0; i < ARRAY_SIZE(rates); i++) |
249 | if (runtime->rate == rates[i]) | 256 | if (runtime->rate == rates[i]) |
250 | dev->pcm_info.rates = 1 << i; | 257 | cdev->pcm_info.rates = 1 << i; |
251 | 258 | ||
252 | snd_pcm_limit_hw_rates(runtime); | 259 | snd_pcm_limit_hw_rates(runtime); |
253 | 260 | ||
254 | bytes_per_sample = BYTES_PER_SAMPLE; | 261 | bytes_per_sample = BYTES_PER_SAMPLE; |
255 | if (dev->spec.data_alignment >= 2) | 262 | if (cdev->spec.data_alignment >= 2) |
256 | bytes_per_sample++; | 263 | bytes_per_sample++; |
257 | 264 | ||
258 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) | 265 | bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) |
259 | * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; | 266 | * bytes_per_sample * CHANNELS_PER_STREAM * cdev->n_streams; |
260 | 267 | ||
261 | if (bpp > MAX_ENDPOINT_SIZE) | 268 | if (bpp > MAX_ENDPOINT_SIZE) |
262 | bpp = MAX_ENDPOINT_SIZE; | 269 | bpp = MAX_ENDPOINT_SIZE; |
263 | 270 | ||
264 | ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate, | 271 | ret = snd_usb_caiaq_set_audio_params(cdev, runtime->rate, |
265 | runtime->sample_bits, bpp); | 272 | runtime->sample_bits, bpp); |
266 | if (ret) | 273 | if (ret) |
267 | return ret; | 274 | return ret; |
268 | 275 | ||
269 | ret = stream_start(dev); | 276 | ret = stream_start(cdev); |
270 | if (ret) | 277 | if (ret) |
271 | return ret; | 278 | return ret; |
272 | 279 | ||
273 | dev->output_running = 0; | 280 | cdev->output_running = 0; |
274 | wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); | 281 | wait_event_timeout(cdev->prepare_wait_queue, cdev->output_running, HZ); |
275 | if (!dev->output_running) { | 282 | if (!cdev->output_running) { |
276 | stream_stop(dev); | 283 | stream_stop(cdev); |
277 | return -EPIPE; | 284 | return -EPIPE; |
278 | } | 285 | } |
279 | 286 | ||
@@ -282,18 +289,19 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) | |||
282 | 289 | ||
283 | static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) | 290 | static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) |
284 | { | 291 | { |
285 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | 292 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
293 | struct device *dev = caiaqdev_to_dev(cdev); | ||
286 | 294 | ||
287 | debug("%s(%p) cmd %d\n", __func__, sub, cmd); | 295 | dev_dbg(dev, "%s(%p) cmd %d\n", __func__, sub, cmd); |
288 | 296 | ||
289 | switch (cmd) { | 297 | switch (cmd) { |
290 | case SNDRV_PCM_TRIGGER_START: | 298 | case SNDRV_PCM_TRIGGER_START: |
291 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 299 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
292 | activate_substream(dev, sub); | 300 | activate_substream(cdev, sub); |
293 | break; | 301 | break; |
294 | case SNDRV_PCM_TRIGGER_STOP: | 302 | case SNDRV_PCM_TRIGGER_STOP: |
295 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 303 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
296 | deactivate_substream(dev, sub); | 304 | deactivate_substream(cdev, sub); |
297 | break; | 305 | break; |
298 | default: | 306 | default: |
299 | return -EINVAL; | 307 | return -EINVAL; |
@@ -306,25 +314,25 @@ static snd_pcm_uframes_t | |||
306 | snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | 314 | snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) |
307 | { | 315 | { |
308 | int index = sub->number; | 316 | int index = sub->number; |
309 | struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); | 317 | struct snd_usb_caiaqdev *cdev = snd_pcm_substream_chip(sub); |
310 | snd_pcm_uframes_t ptr; | 318 | snd_pcm_uframes_t ptr; |
311 | 319 | ||
312 | spin_lock(&dev->spinlock); | 320 | spin_lock(&cdev->spinlock); |
313 | 321 | ||
314 | if (dev->input_panic || dev->output_panic) { | 322 | if (cdev->input_panic || cdev->output_panic) { |
315 | ptr = SNDRV_PCM_POS_XRUN; | 323 | ptr = SNDRV_PCM_POS_XRUN; |
316 | goto unlock; | 324 | goto unlock; |
317 | } | 325 | } |
318 | 326 | ||
319 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 327 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
320 | ptr = bytes_to_frames(sub->runtime, | 328 | ptr = bytes_to_frames(sub->runtime, |
321 | dev->audio_out_buf_pos[index]); | 329 | cdev->audio_out_buf_pos[index]); |
322 | else | 330 | else |
323 | ptr = bytes_to_frames(sub->runtime, | 331 | ptr = bytes_to_frames(sub->runtime, |
324 | dev->audio_in_buf_pos[index]); | 332 | cdev->audio_in_buf_pos[index]); |
325 | 333 | ||
326 | unlock: | 334 | unlock: |
327 | spin_unlock(&dev->spinlock); | 335 | spin_unlock(&cdev->spinlock); |
328 | return ptr; | 336 | return ptr; |
329 | } | 337 | } |
330 | 338 | ||
@@ -340,21 +348,21 @@ static struct snd_pcm_ops snd_usb_caiaq_ops = { | |||
340 | .pointer = snd_usb_caiaq_pcm_pointer | 348 | .pointer = snd_usb_caiaq_pcm_pointer |
341 | }; | 349 | }; |
342 | 350 | ||
343 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, | 351 | static void check_for_elapsed_periods(struct snd_usb_caiaqdev *cdev, |
344 | struct snd_pcm_substream **subs) | 352 | struct snd_pcm_substream **subs) |
345 | { | 353 | { |
346 | int stream, pb, *cnt; | 354 | int stream, pb, *cnt; |
347 | struct snd_pcm_substream *sub; | 355 | struct snd_pcm_substream *sub; |
348 | 356 | ||
349 | for (stream = 0; stream < dev->n_streams; stream++) { | 357 | for (stream = 0; stream < cdev->n_streams; stream++) { |
350 | sub = subs[stream]; | 358 | sub = subs[stream]; |
351 | if (!sub) | 359 | if (!sub) |
352 | continue; | 360 | continue; |
353 | 361 | ||
354 | pb = snd_pcm_lib_period_bytes(sub); | 362 | pb = snd_pcm_lib_period_bytes(sub); |
355 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | 363 | cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? |
356 | &dev->period_out_count[stream] : | 364 | &cdev->period_out_count[stream] : |
357 | &dev->period_in_count[stream]; | 365 | &cdev->period_in_count[stream]; |
358 | 366 | ||
359 | if (*cnt >= pb) { | 367 | if (*cnt >= pb) { |
360 | snd_pcm_period_elapsed(sub); | 368 | snd_pcm_period_elapsed(sub); |
@@ -363,7 +371,7 @@ static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, | |||
363 | } | 371 | } |
364 | } | 372 | } |
365 | 373 | ||
366 | static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, | 374 | static void read_in_urb_mode0(struct snd_usb_caiaqdev *cdev, |
367 | const struct urb *urb, | 375 | const struct urb *urb, |
368 | const struct usb_iso_packet_descriptor *iso) | 376 | const struct usb_iso_packet_descriptor *iso) |
369 | { | 377 | { |
@@ -371,27 +379,27 @@ static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, | |||
371 | struct snd_pcm_substream *sub; | 379 | struct snd_pcm_substream *sub; |
372 | int stream, i; | 380 | int stream, i; |
373 | 381 | ||
374 | if (all_substreams_zero(dev->sub_capture)) | 382 | if (all_substreams_zero(cdev->sub_capture)) |
375 | return; | 383 | return; |
376 | 384 | ||
377 | for (i = 0; i < iso->actual_length;) { | 385 | for (i = 0; i < iso->actual_length;) { |
378 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | 386 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
379 | sub = dev->sub_capture[stream]; | 387 | sub = cdev->sub_capture[stream]; |
380 | if (sub) { | 388 | if (sub) { |
381 | struct snd_pcm_runtime *rt = sub->runtime; | 389 | struct snd_pcm_runtime *rt = sub->runtime; |
382 | char *audio_buf = rt->dma_area; | 390 | char *audio_buf = rt->dma_area; |
383 | int sz = frames_to_bytes(rt, rt->buffer_size); | 391 | int sz = frames_to_bytes(rt, rt->buffer_size); |
384 | audio_buf[dev->audio_in_buf_pos[stream]++] | 392 | audio_buf[cdev->audio_in_buf_pos[stream]++] |
385 | = usb_buf[i]; | 393 | = usb_buf[i]; |
386 | dev->period_in_count[stream]++; | 394 | cdev->period_in_count[stream]++; |
387 | if (dev->audio_in_buf_pos[stream] == sz) | 395 | if (cdev->audio_in_buf_pos[stream] == sz) |
388 | dev->audio_in_buf_pos[stream] = 0; | 396 | cdev->audio_in_buf_pos[stream] = 0; |
389 | } | 397 | } |
390 | } | 398 | } |
391 | } | 399 | } |
392 | } | 400 | } |
393 | 401 | ||
394 | static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, | 402 | static void read_in_urb_mode2(struct snd_usb_caiaqdev *cdev, |
395 | const struct urb *urb, | 403 | const struct urb *urb, |
396 | const struct usb_iso_packet_descriptor *iso) | 404 | const struct usb_iso_packet_descriptor *iso) |
397 | { | 405 | { |
@@ -401,48 +409,49 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, | |||
401 | int stream, i; | 409 | int stream, i; |
402 | 410 | ||
403 | for (i = 0; i < iso->actual_length;) { | 411 | for (i = 0; i < iso->actual_length;) { |
404 | if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { | 412 | if (i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { |
405 | for (stream = 0; | 413 | for (stream = 0; |
406 | stream < dev->n_streams; | 414 | stream < cdev->n_streams; |
407 | stream++, i++) { | 415 | stream++, i++) { |
408 | if (dev->first_packet) | 416 | if (cdev->first_packet) |
409 | continue; | 417 | continue; |
410 | 418 | ||
411 | check_byte = MAKE_CHECKBYTE(dev, stream, i); | 419 | check_byte = MAKE_CHECKBYTE(cdev, stream, i); |
412 | 420 | ||
413 | if ((usb_buf[i] & 0x3f) != check_byte) | 421 | if ((usb_buf[i] & 0x3f) != check_byte) |
414 | dev->input_panic = 1; | 422 | cdev->input_panic = 1; |
415 | 423 | ||
416 | if (usb_buf[i] & 0x80) | 424 | if (usb_buf[i] & 0x80) |
417 | dev->output_panic = 1; | 425 | cdev->output_panic = 1; |
418 | } | 426 | } |
419 | } | 427 | } |
420 | dev->first_packet = 0; | 428 | cdev->first_packet = 0; |
421 | 429 | ||
422 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | 430 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
423 | sub = dev->sub_capture[stream]; | 431 | sub = cdev->sub_capture[stream]; |
424 | if (dev->input_panic) | 432 | if (cdev->input_panic) |
425 | usb_buf[i] = 0; | 433 | usb_buf[i] = 0; |
426 | 434 | ||
427 | if (sub) { | 435 | if (sub) { |
428 | struct snd_pcm_runtime *rt = sub->runtime; | 436 | struct snd_pcm_runtime *rt = sub->runtime; |
429 | char *audio_buf = rt->dma_area; | 437 | char *audio_buf = rt->dma_area; |
430 | int sz = frames_to_bytes(rt, rt->buffer_size); | 438 | int sz = frames_to_bytes(rt, rt->buffer_size); |
431 | audio_buf[dev->audio_in_buf_pos[stream]++] = | 439 | audio_buf[cdev->audio_in_buf_pos[stream]++] = |
432 | usb_buf[i]; | 440 | usb_buf[i]; |
433 | dev->period_in_count[stream]++; | 441 | cdev->period_in_count[stream]++; |
434 | if (dev->audio_in_buf_pos[stream] == sz) | 442 | if (cdev->audio_in_buf_pos[stream] == sz) |
435 | dev->audio_in_buf_pos[stream] = 0; | 443 | cdev->audio_in_buf_pos[stream] = 0; |
436 | } | 444 | } |
437 | } | 445 | } |
438 | } | 446 | } |
439 | } | 447 | } |
440 | 448 | ||
441 | static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, | 449 | static void read_in_urb_mode3(struct snd_usb_caiaqdev *cdev, |
442 | const struct urb *urb, | 450 | const struct urb *urb, |
443 | const struct usb_iso_packet_descriptor *iso) | 451 | const struct usb_iso_packet_descriptor *iso) |
444 | { | 452 | { |
445 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; | 453 | unsigned char *usb_buf = urb->transfer_buffer + iso->offset; |
454 | struct device *dev = caiaqdev_to_dev(cdev); | ||
446 | int stream, i; | 455 | int stream, i; |
447 | 456 | ||
448 | /* paranoia check */ | 457 | /* paranoia check */ |
@@ -450,12 +459,12 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, | |||
450 | return; | 459 | return; |
451 | 460 | ||
452 | for (i = 0; i < iso->actual_length;) { | 461 | for (i = 0; i < iso->actual_length;) { |
453 | for (stream = 0; stream < dev->n_streams; stream++) { | 462 | for (stream = 0; stream < cdev->n_streams; stream++) { |
454 | struct snd_pcm_substream *sub = dev->sub_capture[stream]; | 463 | struct snd_pcm_substream *sub = cdev->sub_capture[stream]; |
455 | char *audio_buf = NULL; | 464 | char *audio_buf = NULL; |
456 | int c, n, sz = 0; | 465 | int c, n, sz = 0; |
457 | 466 | ||
458 | if (sub && !dev->input_panic) { | 467 | if (sub && !cdev->input_panic) { |
459 | struct snd_pcm_runtime *rt = sub->runtime; | 468 | struct snd_pcm_runtime *rt = sub->runtime; |
460 | audio_buf = rt->dma_area; | 469 | audio_buf = rt->dma_area; |
461 | sz = frames_to_bytes(rt, rt->buffer_size); | 470 | sz = frames_to_bytes(rt, rt->buffer_size); |
@@ -465,23 +474,23 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, | |||
465 | /* 3 audio data bytes, followed by 1 check byte */ | 474 | /* 3 audio data bytes, followed by 1 check byte */ |
466 | if (audio_buf) { | 475 | if (audio_buf) { |
467 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { | 476 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { |
468 | audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; | 477 | audio_buf[cdev->audio_in_buf_pos[stream]++] = usb_buf[i+n]; |
469 | 478 | ||
470 | if (dev->audio_in_buf_pos[stream] == sz) | 479 | if (cdev->audio_in_buf_pos[stream] == sz) |
471 | dev->audio_in_buf_pos[stream] = 0; | 480 | cdev->audio_in_buf_pos[stream] = 0; |
472 | } | 481 | } |
473 | 482 | ||
474 | dev->period_in_count[stream] += BYTES_PER_SAMPLE; | 483 | cdev->period_in_count[stream] += BYTES_PER_SAMPLE; |
475 | } | 484 | } |
476 | 485 | ||
477 | i += BYTES_PER_SAMPLE; | 486 | i += BYTES_PER_SAMPLE; |
478 | 487 | ||
479 | if (usb_buf[i] != ((stream << 1) | c) && | 488 | if (usb_buf[i] != ((stream << 1) | c) && |
480 | !dev->first_packet) { | 489 | !cdev->first_packet) { |
481 | if (!dev->input_panic) | 490 | if (!cdev->input_panic) |
482 | printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n", | 491 | dev_warn(dev, " EXPECTED: %02x got %02x, c %d, stream %d, i %d\n", |
483 | ((stream << 1) | c), usb_buf[i], c, stream, i); | 492 | ((stream << 1) | c), usb_buf[i], c, stream, i); |
484 | dev->input_panic = 1; | 493 | cdev->input_panic = 1; |
485 | } | 494 | } |
486 | 495 | ||
487 | i++; | 496 | i++; |
@@ -489,41 +498,43 @@ static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev, | |||
489 | } | 498 | } |
490 | } | 499 | } |
491 | 500 | ||
492 | if (dev->first_packet > 0) | 501 | if (cdev->first_packet > 0) |
493 | dev->first_packet--; | 502 | cdev->first_packet--; |
494 | } | 503 | } |
495 | 504 | ||
496 | static void read_in_urb(struct snd_usb_caiaqdev *dev, | 505 | static void read_in_urb(struct snd_usb_caiaqdev *cdev, |
497 | const struct urb *urb, | 506 | const struct urb *urb, |
498 | const struct usb_iso_packet_descriptor *iso) | 507 | const struct usb_iso_packet_descriptor *iso) |
499 | { | 508 | { |
500 | if (!dev->streaming) | 509 | struct device *dev = caiaqdev_to_dev(cdev); |
510 | |||
511 | if (!cdev->streaming) | ||
501 | return; | 512 | return; |
502 | 513 | ||
503 | if (iso->actual_length < dev->bpp) | 514 | if (iso->actual_length < cdev->bpp) |
504 | return; | 515 | return; |
505 | 516 | ||
506 | switch (dev->spec.data_alignment) { | 517 | switch (cdev->spec.data_alignment) { |
507 | case 0: | 518 | case 0: |
508 | read_in_urb_mode0(dev, urb, iso); | 519 | read_in_urb_mode0(cdev, urb, iso); |
509 | break; | 520 | break; |
510 | case 2: | 521 | case 2: |
511 | read_in_urb_mode2(dev, urb, iso); | 522 | read_in_urb_mode2(cdev, urb, iso); |
512 | break; | 523 | break; |
513 | case 3: | 524 | case 3: |
514 | read_in_urb_mode3(dev, urb, iso); | 525 | read_in_urb_mode3(cdev, urb, iso); |
515 | break; | 526 | break; |
516 | } | 527 | } |
517 | 528 | ||
518 | if ((dev->input_panic || dev->output_panic) && !dev->warned) { | 529 | if ((cdev->input_panic || cdev->output_panic) && !cdev->warned) { |
519 | debug("streaming error detected %s %s\n", | 530 | dev_warn(dev, "streaming error detected %s %s\n", |
520 | dev->input_panic ? "(input)" : "", | 531 | cdev->input_panic ? "(input)" : "", |
521 | dev->output_panic ? "(output)" : ""); | 532 | cdev->output_panic ? "(output)" : ""); |
522 | dev->warned = 1; | 533 | cdev->warned = 1; |
523 | } | 534 | } |
524 | } | 535 | } |
525 | 536 | ||
526 | static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev, | 537 | static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *cdev, |
527 | struct urb *urb, | 538 | struct urb *urb, |
528 | const struct usb_iso_packet_descriptor *iso) | 539 | const struct usb_iso_packet_descriptor *iso) |
529 | { | 540 | { |
@@ -532,32 +543,32 @@ static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev, | |||
532 | int stream, i; | 543 | int stream, i; |
533 | 544 | ||
534 | for (i = 0; i < iso->length;) { | 545 | for (i = 0; i < iso->length;) { |
535 | for (stream = 0; stream < dev->n_streams; stream++, i++) { | 546 | for (stream = 0; stream < cdev->n_streams; stream++, i++) { |
536 | sub = dev->sub_playback[stream]; | 547 | sub = cdev->sub_playback[stream]; |
537 | if (sub) { | 548 | if (sub) { |
538 | struct snd_pcm_runtime *rt = sub->runtime; | 549 | struct snd_pcm_runtime *rt = sub->runtime; |
539 | char *audio_buf = rt->dma_area; | 550 | char *audio_buf = rt->dma_area; |
540 | int sz = frames_to_bytes(rt, rt->buffer_size); | 551 | int sz = frames_to_bytes(rt, rt->buffer_size); |
541 | usb_buf[i] = | 552 | usb_buf[i] = |
542 | audio_buf[dev->audio_out_buf_pos[stream]]; | 553 | audio_buf[cdev->audio_out_buf_pos[stream]]; |
543 | dev->period_out_count[stream]++; | 554 | cdev->period_out_count[stream]++; |
544 | dev->audio_out_buf_pos[stream]++; | 555 | cdev->audio_out_buf_pos[stream]++; |
545 | if (dev->audio_out_buf_pos[stream] == sz) | 556 | if (cdev->audio_out_buf_pos[stream] == sz) |
546 | dev->audio_out_buf_pos[stream] = 0; | 557 | cdev->audio_out_buf_pos[stream] = 0; |
547 | } else | 558 | } else |
548 | usb_buf[i] = 0; | 559 | usb_buf[i] = 0; |
549 | } | 560 | } |
550 | 561 | ||
551 | /* fill in the check bytes */ | 562 | /* fill in the check bytes */ |
552 | if (dev->spec.data_alignment == 2 && | 563 | if (cdev->spec.data_alignment == 2 && |
553 | i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == | 564 | i % (cdev->n_streams * BYTES_PER_SAMPLE_USB) == |
554 | (dev->n_streams * CHANNELS_PER_STREAM)) | 565 | (cdev->n_streams * CHANNELS_PER_STREAM)) |
555 | for (stream = 0; stream < dev->n_streams; stream++, i++) | 566 | for (stream = 0; stream < cdev->n_streams; stream++, i++) |
556 | usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); | 567 | usb_buf[i] = MAKE_CHECKBYTE(cdev, stream, i); |
557 | } | 568 | } |
558 | } | 569 | } |
559 | 570 | ||
560 | static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, | 571 | static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *cdev, |
561 | struct urb *urb, | 572 | struct urb *urb, |
562 | const struct usb_iso_packet_descriptor *iso) | 573 | const struct usb_iso_packet_descriptor *iso) |
563 | { | 574 | { |
@@ -565,8 +576,8 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, | |||
565 | int stream, i; | 576 | int stream, i; |
566 | 577 | ||
567 | for (i = 0; i < iso->length;) { | 578 | for (i = 0; i < iso->length;) { |
568 | for (stream = 0; stream < dev->n_streams; stream++) { | 579 | for (stream = 0; stream < cdev->n_streams; stream++) { |
569 | struct snd_pcm_substream *sub = dev->sub_playback[stream]; | 580 | struct snd_pcm_substream *sub = cdev->sub_playback[stream]; |
570 | char *audio_buf = NULL; | 581 | char *audio_buf = NULL; |
571 | int c, n, sz = 0; | 582 | int c, n, sz = 0; |
572 | 583 | ||
@@ -579,17 +590,17 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, | |||
579 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { | 590 | for (c = 0; c < CHANNELS_PER_STREAM; c++) { |
580 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { | 591 | for (n = 0; n < BYTES_PER_SAMPLE; n++) { |
581 | if (audio_buf) { | 592 | if (audio_buf) { |
582 | usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++]; | 593 | usb_buf[i+n] = audio_buf[cdev->audio_out_buf_pos[stream]++]; |
583 | 594 | ||
584 | if (dev->audio_out_buf_pos[stream] == sz) | 595 | if (cdev->audio_out_buf_pos[stream] == sz) |
585 | dev->audio_out_buf_pos[stream] = 0; | 596 | cdev->audio_out_buf_pos[stream] = 0; |
586 | } else { | 597 | } else { |
587 | usb_buf[i+n] = 0; | 598 | usb_buf[i+n] = 0; |
588 | } | 599 | } |
589 | } | 600 | } |
590 | 601 | ||
591 | if (audio_buf) | 602 | if (audio_buf) |
592 | dev->period_out_count[stream] += BYTES_PER_SAMPLE; | 603 | cdev->period_out_count[stream] += BYTES_PER_SAMPLE; |
593 | 604 | ||
594 | i += BYTES_PER_SAMPLE; | 605 | i += BYTES_PER_SAMPLE; |
595 | 606 | ||
@@ -600,17 +611,17 @@ static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev, | |||
600 | } | 611 | } |
601 | } | 612 | } |
602 | 613 | ||
603 | static inline void fill_out_urb(struct snd_usb_caiaqdev *dev, | 614 | static inline void fill_out_urb(struct snd_usb_caiaqdev *cdev, |
604 | struct urb *urb, | 615 | struct urb *urb, |
605 | const struct usb_iso_packet_descriptor *iso) | 616 | const struct usb_iso_packet_descriptor *iso) |
606 | { | 617 | { |
607 | switch (dev->spec.data_alignment) { | 618 | switch (cdev->spec.data_alignment) { |
608 | case 0: | 619 | case 0: |
609 | case 2: | 620 | case 2: |
610 | fill_out_urb_mode_0(dev, urb, iso); | 621 | fill_out_urb_mode_0(cdev, urb, iso); |
611 | break; | 622 | break; |
612 | case 3: | 623 | case 3: |
613 | fill_out_urb_mode_3(dev, urb, iso); | 624 | fill_out_urb_mode_3(cdev, urb, iso); |
614 | break; | 625 | break; |
615 | } | 626 | } |
616 | } | 627 | } |
@@ -618,7 +629,8 @@ static inline void fill_out_urb(struct snd_usb_caiaqdev *dev, | |||
618 | static void read_completed(struct urb *urb) | 629 | static void read_completed(struct urb *urb) |
619 | { | 630 | { |
620 | struct snd_usb_caiaq_cb_info *info = urb->context; | 631 | struct snd_usb_caiaq_cb_info *info = urb->context; |
621 | struct snd_usb_caiaqdev *dev; | 632 | struct snd_usb_caiaqdev *cdev; |
633 | struct device *dev; | ||
622 | struct urb *out = NULL; | 634 | struct urb *out = NULL; |
623 | int i, frame, len, send_it = 0, outframe = 0; | 635 | int i, frame, len, send_it = 0, outframe = 0; |
624 | size_t offset = 0; | 636 | size_t offset = 0; |
@@ -626,20 +638,21 @@ static void read_completed(struct urb *urb) | |||
626 | if (urb->status || !info) | 638 | if (urb->status || !info) |
627 | return; | 639 | return; |
628 | 640 | ||
629 | dev = info->dev; | 641 | cdev = info->cdev; |
642 | dev = caiaqdev_to_dev(cdev); | ||
630 | 643 | ||
631 | if (!dev->streaming) | 644 | if (!cdev->streaming) |
632 | return; | 645 | return; |
633 | 646 | ||
634 | /* find an unused output urb that is unused */ | 647 | /* find an unused output urb that is unused */ |
635 | for (i = 0; i < N_URBS; i++) | 648 | for (i = 0; i < N_URBS; i++) |
636 | if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { | 649 | if (test_and_set_bit(i, &cdev->outurb_active_mask) == 0) { |
637 | out = dev->data_urbs_out[i]; | 650 | out = cdev->data_urbs_out[i]; |
638 | break; | 651 | break; |
639 | } | 652 | } |
640 | 653 | ||
641 | if (!out) { | 654 | if (!out) { |
642 | log("Unable to find an output urb to use\n"); | 655 | dev_err(dev, "Unable to find an output urb to use\n"); |
643 | goto requeue; | 656 | goto requeue; |
644 | } | 657 | } |
645 | 658 | ||
@@ -656,12 +669,12 @@ static void read_completed(struct urb *urb) | |||
656 | offset += len; | 669 | offset += len; |
657 | 670 | ||
658 | if (len > 0) { | 671 | if (len > 0) { |
659 | spin_lock(&dev->spinlock); | 672 | spin_lock(&cdev->spinlock); |
660 | fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); | 673 | fill_out_urb(cdev, out, &out->iso_frame_desc[outframe]); |
661 | read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); | 674 | read_in_urb(cdev, urb, &urb->iso_frame_desc[frame]); |
662 | spin_unlock(&dev->spinlock); | 675 | spin_unlock(&cdev->spinlock); |
663 | check_for_elapsed_periods(dev, dev->sub_playback); | 676 | check_for_elapsed_periods(cdev, cdev->sub_playback); |
664 | check_for_elapsed_periods(dev, dev->sub_capture); | 677 | check_for_elapsed_periods(cdev, cdev->sub_capture); |
665 | send_it = 1; | 678 | send_it = 1; |
666 | } | 679 | } |
667 | 680 | ||
@@ -670,11 +683,10 @@ static void read_completed(struct urb *urb) | |||
670 | 683 | ||
671 | if (send_it) { | 684 | if (send_it) { |
672 | out->number_of_packets = outframe; | 685 | out->number_of_packets = outframe; |
673 | out->transfer_flags = URB_ISO_ASAP; | ||
674 | usb_submit_urb(out, GFP_ATOMIC); | 686 | usb_submit_urb(out, GFP_ATOMIC); |
675 | } else { | 687 | } else { |
676 | struct snd_usb_caiaq_cb_info *oinfo = out->context; | 688 | struct snd_usb_caiaq_cb_info *oinfo = out->context; |
677 | clear_bit(oinfo->index, &dev->outurb_active_mask); | 689 | clear_bit(oinfo->index, &cdev->outurb_active_mask); |
678 | } | 690 | } |
679 | 691 | ||
680 | requeue: | 692 | requeue: |
@@ -686,28 +698,28 @@ requeue: | |||
686 | } | 698 | } |
687 | 699 | ||
688 | urb->number_of_packets = FRAMES_PER_URB; | 700 | urb->number_of_packets = FRAMES_PER_URB; |
689 | urb->transfer_flags = URB_ISO_ASAP; | ||
690 | usb_submit_urb(urb, GFP_ATOMIC); | 701 | usb_submit_urb(urb, GFP_ATOMIC); |
691 | } | 702 | } |
692 | 703 | ||
693 | static void write_completed(struct urb *urb) | 704 | static void write_completed(struct urb *urb) |
694 | { | 705 | { |
695 | struct snd_usb_caiaq_cb_info *info = urb->context; | 706 | struct snd_usb_caiaq_cb_info *info = urb->context; |
696 | struct snd_usb_caiaqdev *dev = info->dev; | 707 | struct snd_usb_caiaqdev *cdev = info->cdev; |
697 | 708 | ||
698 | if (!dev->output_running) { | 709 | if (!cdev->output_running) { |
699 | dev->output_running = 1; | 710 | cdev->output_running = 1; |
700 | wake_up(&dev->prepare_wait_queue); | 711 | wake_up(&cdev->prepare_wait_queue); |
701 | } | 712 | } |
702 | 713 | ||
703 | clear_bit(info->index, &dev->outurb_active_mask); | 714 | clear_bit(info->index, &cdev->outurb_active_mask); |
704 | } | 715 | } |
705 | 716 | ||
706 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | 717 | static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) |
707 | { | 718 | { |
708 | int i, frame; | 719 | int i, frame; |
709 | struct urb **urbs; | 720 | struct urb **urbs; |
710 | struct usb_device *usb_dev = dev->chip.dev; | 721 | struct usb_device *usb_dev = cdev->chip.dev; |
722 | struct device *dev = caiaqdev_to_dev(cdev); | ||
711 | unsigned int pipe; | 723 | unsigned int pipe; |
712 | 724 | ||
713 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? | 725 | pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? |
@@ -716,7 +728,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
716 | 728 | ||
717 | urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); | 729 | urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); |
718 | if (!urbs) { | 730 | if (!urbs) { |
719 | log("unable to kmalloc() urbs, OOM!?\n"); | 731 | dev_err(dev, "unable to kmalloc() urbs, OOM!?\n"); |
720 | *ret = -ENOMEM; | 732 | *ret = -ENOMEM; |
721 | return NULL; | 733 | return NULL; |
722 | } | 734 | } |
@@ -724,7 +736,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
724 | for (i = 0; i < N_URBS; i++) { | 736 | for (i = 0; i < N_URBS; i++) { |
725 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); | 737 | urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); |
726 | if (!urbs[i]) { | 738 | if (!urbs[i]) { |
727 | log("unable to usb_alloc_urb(), OOM!?\n"); | 739 | dev_err(dev, "unable to usb_alloc_urb(), OOM!?\n"); |
728 | *ret = -ENOMEM; | 740 | *ret = -ENOMEM; |
729 | return urbs; | 741 | return urbs; |
730 | } | 742 | } |
@@ -732,7 +744,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
732 | urbs[i]->transfer_buffer = | 744 | urbs[i]->transfer_buffer = |
733 | kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); | 745 | kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); |
734 | if (!urbs[i]->transfer_buffer) { | 746 | if (!urbs[i]->transfer_buffer) { |
735 | log("unable to kmalloc() transfer buffer, OOM!?\n"); | 747 | dev_err(dev, "unable to kmalloc() transfer buffer, OOM!?\n"); |
736 | *ret = -ENOMEM; | 748 | *ret = -ENOMEM; |
737 | return urbs; | 749 | return urbs; |
738 | } | 750 | } |
@@ -749,9 +761,8 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) | |||
749 | urbs[i]->pipe = pipe; | 761 | urbs[i]->pipe = pipe; |
750 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB | 762 | urbs[i]->transfer_buffer_length = FRAMES_PER_URB |
751 | * BYTES_PER_FRAME; | 763 | * BYTES_PER_FRAME; |
752 | urbs[i]->context = &dev->data_cb_info[i]; | 764 | urbs[i]->context = &cdev->data_cb_info[i]; |
753 | urbs[i]->interval = 1; | 765 | urbs[i]->interval = 1; |
754 | urbs[i]->transfer_flags = URB_ISO_ASAP; | ||
755 | urbs[i]->number_of_packets = FRAMES_PER_URB; | 766 | urbs[i]->number_of_packets = FRAMES_PER_URB; |
756 | urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? | 767 | urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? |
757 | read_completed : write_completed; | 768 | read_completed : write_completed; |
@@ -780,110 +791,113 @@ static void free_urbs(struct urb **urbs) | |||
780 | kfree(urbs); | 791 | kfree(urbs); |
781 | } | 792 | } |
782 | 793 | ||
783 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) | 794 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) |
784 | { | 795 | { |
785 | int i, ret; | 796 | int i, ret; |
797 | struct device *dev = caiaqdev_to_dev(cdev); | ||
786 | 798 | ||
787 | dev->n_audio_in = max(dev->spec.num_analog_audio_in, | 799 | cdev->n_audio_in = max(cdev->spec.num_analog_audio_in, |
788 | dev->spec.num_digital_audio_in) / | 800 | cdev->spec.num_digital_audio_in) / |
789 | CHANNELS_PER_STREAM; | 801 | CHANNELS_PER_STREAM; |
790 | dev->n_audio_out = max(dev->spec.num_analog_audio_out, | 802 | cdev->n_audio_out = max(cdev->spec.num_analog_audio_out, |
791 | dev->spec.num_digital_audio_out) / | 803 | cdev->spec.num_digital_audio_out) / |
792 | CHANNELS_PER_STREAM; | 804 | CHANNELS_PER_STREAM; |
793 | dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); | 805 | cdev->n_streams = max(cdev->n_audio_in, cdev->n_audio_out); |
794 | 806 | ||
795 | debug("dev->n_audio_in = %d\n", dev->n_audio_in); | 807 | dev_dbg(dev, "cdev->n_audio_in = %d\n", cdev->n_audio_in); |
796 | debug("dev->n_audio_out = %d\n", dev->n_audio_out); | 808 | dev_dbg(dev, "cdev->n_audio_out = %d\n", cdev->n_audio_out); |
797 | debug("dev->n_streams = %d\n", dev->n_streams); | 809 | dev_dbg(dev, "cdev->n_streams = %d\n", cdev->n_streams); |
798 | 810 | ||
799 | if (dev->n_streams > MAX_STREAMS) { | 811 | if (cdev->n_streams > MAX_STREAMS) { |
800 | log("unable to initialize device, too many streams.\n"); | 812 | dev_err(dev, "unable to initialize device, too many streams.\n"); |
801 | return -EINVAL; | 813 | return -EINVAL; |
802 | } | 814 | } |
803 | 815 | ||
804 | ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, | 816 | ret = snd_pcm_new(cdev->chip.card, cdev->product_name, 0, |
805 | dev->n_audio_out, dev->n_audio_in, &dev->pcm); | 817 | cdev->n_audio_out, cdev->n_audio_in, &cdev->pcm); |
806 | 818 | ||
807 | if (ret < 0) { | 819 | if (ret < 0) { |
808 | log("snd_pcm_new() returned %d\n", ret); | 820 | dev_err(dev, "snd_pcm_new() returned %d\n", ret); |
809 | return ret; | 821 | return ret; |
810 | } | 822 | } |
811 | 823 | ||
812 | dev->pcm->private_data = dev; | 824 | cdev->pcm->private_data = cdev; |
813 | strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name)); | 825 | strlcpy(cdev->pcm->name, cdev->product_name, sizeof(cdev->pcm->name)); |
814 | 826 | ||
815 | memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); | 827 | memset(cdev->sub_playback, 0, sizeof(cdev->sub_playback)); |
816 | memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); | 828 | memset(cdev->sub_capture, 0, sizeof(cdev->sub_capture)); |
817 | 829 | ||
818 | memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, | 830 | memcpy(&cdev->pcm_info, &snd_usb_caiaq_pcm_hardware, |
819 | sizeof(snd_usb_caiaq_pcm_hardware)); | 831 | sizeof(snd_usb_caiaq_pcm_hardware)); |
820 | 832 | ||
821 | /* setup samplerates */ | 833 | /* setup samplerates */ |
822 | dev->samplerates = dev->pcm_info.rates; | 834 | cdev->samplerates = cdev->pcm_info.rates; |
823 | switch (dev->chip.usb_id) { | 835 | switch (cdev->chip.usb_id) { |
824 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 836 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
825 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 837 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
826 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): | 838 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO): |
827 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): | 839 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE): |
828 | dev->samplerates |= SNDRV_PCM_RATE_192000; | 840 | cdev->samplerates |= SNDRV_PCM_RATE_192000; |
829 | /* fall thru */ | 841 | /* fall thru */ |
830 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): | 842 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ): |
831 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | 843 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
832 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 844 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
833 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2): | 845 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2): |
834 | dev->samplerates |= SNDRV_PCM_RATE_88200; | 846 | cdev->samplerates |= SNDRV_PCM_RATE_88200; |
835 | break; | 847 | break; |
836 | } | 848 | } |
837 | 849 | ||
838 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, | 850 | snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_PLAYBACK, |
839 | &snd_usb_caiaq_ops); | 851 | &snd_usb_caiaq_ops); |
840 | snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, | 852 | snd_pcm_set_ops(cdev->pcm, SNDRV_PCM_STREAM_CAPTURE, |
841 | &snd_usb_caiaq_ops); | 853 | &snd_usb_caiaq_ops); |
842 | 854 | ||
843 | snd_pcm_lib_preallocate_pages_for_all(dev->pcm, | 855 | snd_pcm_lib_preallocate_pages_for_all(cdev->pcm, |
844 | SNDRV_DMA_TYPE_CONTINUOUS, | 856 | SNDRV_DMA_TYPE_CONTINUOUS, |
845 | snd_dma_continuous_data(GFP_KERNEL), | 857 | snd_dma_continuous_data(GFP_KERNEL), |
846 | MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); | 858 | MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); |
847 | 859 | ||
848 | dev->data_cb_info = | 860 | cdev->data_cb_info = |
849 | kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, | 861 | kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, |
850 | GFP_KERNEL); | 862 | GFP_KERNEL); |
851 | 863 | ||
852 | if (!dev->data_cb_info) | 864 | if (!cdev->data_cb_info) |
853 | return -ENOMEM; | 865 | return -ENOMEM; |
854 | 866 | ||
855 | dev->outurb_active_mask = 0; | 867 | cdev->outurb_active_mask = 0; |
856 | BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8)); | 868 | BUILD_BUG_ON(N_URBS > (sizeof(cdev->outurb_active_mask) * 8)); |
857 | 869 | ||
858 | for (i = 0; i < N_URBS; i++) { | 870 | for (i = 0; i < N_URBS; i++) { |
859 | dev->data_cb_info[i].dev = dev; | 871 | cdev->data_cb_info[i].cdev = cdev; |
860 | dev->data_cb_info[i].index = i; | 872 | cdev->data_cb_info[i].index = i; |
861 | } | 873 | } |
862 | 874 | ||
863 | dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); | 875 | cdev->data_urbs_in = alloc_urbs(cdev, SNDRV_PCM_STREAM_CAPTURE, &ret); |
864 | if (ret < 0) { | 876 | if (ret < 0) { |
865 | kfree(dev->data_cb_info); | 877 | kfree(cdev->data_cb_info); |
866 | free_urbs(dev->data_urbs_in); | 878 | free_urbs(cdev->data_urbs_in); |
867 | return ret; | 879 | return ret; |
868 | } | 880 | } |
869 | 881 | ||
870 | dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); | 882 | cdev->data_urbs_out = alloc_urbs(cdev, SNDRV_PCM_STREAM_PLAYBACK, &ret); |
871 | if (ret < 0) { | 883 | if (ret < 0) { |
872 | kfree(dev->data_cb_info); | 884 | kfree(cdev->data_cb_info); |
873 | free_urbs(dev->data_urbs_in); | 885 | free_urbs(cdev->data_urbs_in); |
874 | free_urbs(dev->data_urbs_out); | 886 | free_urbs(cdev->data_urbs_out); |
875 | return ret; | 887 | return ret; |
876 | } | 888 | } |
877 | 889 | ||
878 | return 0; | 890 | return 0; |
879 | } | 891 | } |
880 | 892 | ||
881 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev) | 893 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev) |
882 | { | 894 | { |
883 | debug("%s(%p)\n", __func__, dev); | 895 | struct device *dev = caiaqdev_to_dev(cdev); |
884 | stream_stop(dev); | 896 | |
885 | free_urbs(dev->data_urbs_in); | 897 | dev_dbg(dev, "%s(%p)\n", __func__, cdev); |
886 | free_urbs(dev->data_urbs_out); | 898 | stream_stop(cdev); |
887 | kfree(dev->data_cb_info); | 899 | free_urbs(cdev->data_urbs_in); |
900 | free_urbs(cdev->data_urbs_out); | ||
901 | kfree(cdev->data_cb_info); | ||
888 | } | 902 | } |
889 | 903 | ||
diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h index 8ab1f8d9529e..bdf155300a8a 100644 --- a/sound/usb/caiaq/audio.h +++ b/sound/usb/caiaq/audio.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef CAIAQ_AUDIO_H | 1 | #ifndef CAIAQ_AUDIO_H |
2 | #define CAIAQ_AUDIO_H | 2 | #define CAIAQ_AUDIO_H |
3 | 3 | ||
4 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev); | 4 | int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev); |
5 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev); | 5 | void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev); |
6 | 6 | ||
7 | #endif /* CAIAQ_AUDIO_H */ | 7 | #endif /* CAIAQ_AUDIO_H */ |
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index adb8d03267a0..ae6b50f9ed56 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/device.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
22 | #include <sound/control.h> | 23 | #include <sound/control.h> |
@@ -32,7 +33,7 @@ static int control_info(struct snd_kcontrol *kcontrol, | |||
32 | struct snd_ctl_elem_info *uinfo) | 33 | struct snd_ctl_elem_info *uinfo) |
33 | { | 34 | { |
34 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); | 35 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); |
35 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 36 | struct snd_usb_caiaqdev *cdev = caiaqdev(chip->card); |
36 | int pos = kcontrol->private_value; | 37 | int pos = kcontrol->private_value; |
37 | int is_intval = pos & CNT_INTVAL; | 38 | int is_intval = pos & CNT_INTVAL; |
38 | int maxval = 63; | 39 | int maxval = 63; |
@@ -40,7 +41,7 @@ static int control_info(struct snd_kcontrol *kcontrol, | |||
40 | uinfo->count = 1; | 41 | uinfo->count = 1; |
41 | pos &= ~CNT_INTVAL; | 42 | pos &= ~CNT_INTVAL; |
42 | 43 | ||
43 | switch (dev->chip.usb_id) { | 44 | switch (cdev->chip.usb_id) { |
44 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 45 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
45 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | 46 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
46 | if (pos == 0) { | 47 | if (pos == 0) { |
@@ -78,15 +79,15 @@ static int control_get(struct snd_kcontrol *kcontrol, | |||
78 | struct snd_ctl_elem_value *ucontrol) | 79 | struct snd_ctl_elem_value *ucontrol) |
79 | { | 80 | { |
80 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); | 81 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); |
81 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 82 | struct snd_usb_caiaqdev *cdev = caiaqdev(chip->card); |
82 | int pos = kcontrol->private_value; | 83 | int pos = kcontrol->private_value; |
83 | 84 | ||
84 | if (pos & CNT_INTVAL) | 85 | if (pos & CNT_INTVAL) |
85 | ucontrol->value.integer.value[0] | 86 | ucontrol->value.integer.value[0] |
86 | = dev->control_state[pos & ~CNT_INTVAL]; | 87 | = cdev->control_state[pos & ~CNT_INTVAL]; |
87 | else | 88 | else |
88 | ucontrol->value.integer.value[0] | 89 | ucontrol->value.integer.value[0] |
89 | = !!(dev->control_state[pos / 8] & (1 << pos % 8)); | 90 | = !!(cdev->control_state[pos / 8] & (1 << pos % 8)); |
90 | 91 | ||
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
@@ -95,43 +96,43 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
95 | struct snd_ctl_elem_value *ucontrol) | 96 | struct snd_ctl_elem_value *ucontrol) |
96 | { | 97 | { |
97 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); | 98 | struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); |
98 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 99 | struct snd_usb_caiaqdev *cdev = caiaqdev(chip->card); |
99 | int pos = kcontrol->private_value; | 100 | int pos = kcontrol->private_value; |
100 | int v = ucontrol->value.integer.value[0]; | 101 | int v = ucontrol->value.integer.value[0]; |
101 | unsigned char cmd = EP1_CMD_WRITE_IO; | 102 | unsigned char cmd = EP1_CMD_WRITE_IO; |
102 | 103 | ||
103 | if (dev->chip.usb_id == | 104 | if (cdev->chip.usb_id == |
104 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) | 105 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) |
105 | cmd = EP1_CMD_DIMM_LEDS; | 106 | cmd = EP1_CMD_DIMM_LEDS; |
106 | 107 | ||
107 | if (pos & CNT_INTVAL) { | 108 | if (pos & CNT_INTVAL) { |
108 | int i = pos & ~CNT_INTVAL; | 109 | int i = pos & ~CNT_INTVAL; |
109 | 110 | ||
110 | dev->control_state[i] = v; | 111 | cdev->control_state[i] = v; |
111 | 112 | ||
112 | if (dev->chip.usb_id == | 113 | if (cdev->chip.usb_id == |
113 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) { | 114 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) { |
114 | int actual_len; | 115 | int actual_len; |
115 | 116 | ||
116 | dev->ep8_out_buf[0] = i; | 117 | cdev->ep8_out_buf[0] = i; |
117 | dev->ep8_out_buf[1] = v; | 118 | cdev->ep8_out_buf[1] = v; |
118 | 119 | ||
119 | usb_bulk_msg(dev->chip.dev, | 120 | usb_bulk_msg(cdev->chip.dev, |
120 | usb_sndbulkpipe(dev->chip.dev, 8), | 121 | usb_sndbulkpipe(cdev->chip.dev, 8), |
121 | dev->ep8_out_buf, sizeof(dev->ep8_out_buf), | 122 | cdev->ep8_out_buf, sizeof(cdev->ep8_out_buf), |
122 | &actual_len, 200); | 123 | &actual_len, 200); |
123 | } else { | 124 | } else { |
124 | snd_usb_caiaq_send_command(dev, cmd, | 125 | snd_usb_caiaq_send_command(cdev, cmd, |
125 | dev->control_state, sizeof(dev->control_state)); | 126 | cdev->control_state, sizeof(cdev->control_state)); |
126 | } | 127 | } |
127 | } else { | 128 | } else { |
128 | if (v) | 129 | if (v) |
129 | dev->control_state[pos / 8] |= 1 << (pos % 8); | 130 | cdev->control_state[pos / 8] |= 1 << (pos % 8); |
130 | else | 131 | else |
131 | dev->control_state[pos / 8] &= ~(1 << (pos % 8)); | 132 | cdev->control_state[pos / 8] &= ~(1 << (pos % 8)); |
132 | 133 | ||
133 | snd_usb_caiaq_send_command(dev, cmd, | 134 | snd_usb_caiaq_send_command(cdev, cmd, |
134 | dev->control_state, sizeof(dev->control_state)); | 135 | cdev->control_state, sizeof(cdev->control_state)); |
135 | } | 136 | } |
136 | 137 | ||
137 | return 1; | 138 | return 1; |
@@ -490,7 +491,7 @@ static struct caiaq_controller kontrols4_controller[] = { | |||
490 | }; | 491 | }; |
491 | 492 | ||
492 | static int add_controls(struct caiaq_controller *c, int num, | 493 | static int add_controls(struct caiaq_controller *c, int num, |
493 | struct snd_usb_caiaqdev *dev) | 494 | struct snd_usb_caiaqdev *cdev) |
494 | { | 495 | { |
495 | int i, ret; | 496 | int i, ret; |
496 | struct snd_kcontrol *kc; | 497 | struct snd_kcontrol *kc; |
@@ -498,8 +499,8 @@ static int add_controls(struct caiaq_controller *c, int num, | |||
498 | for (i = 0; i < num; i++, c++) { | 499 | for (i = 0; i < num; i++, c++) { |
499 | kcontrol_template.name = c->name; | 500 | kcontrol_template.name = c->name; |
500 | kcontrol_template.private_value = c->index; | 501 | kcontrol_template.private_value = c->index; |
501 | kc = snd_ctl_new1(&kcontrol_template, dev); | 502 | kc = snd_ctl_new1(&kcontrol_template, cdev); |
502 | ret = snd_ctl_add(dev->chip.card, kc); | 503 | ret = snd_ctl_add(cdev->chip.card, kc); |
503 | if (ret < 0) | 504 | if (ret < 0) |
504 | return ret; | 505 | return ret; |
505 | } | 506 | } |
@@ -507,50 +508,50 @@ static int add_controls(struct caiaq_controller *c, int num, | |||
507 | return 0; | 508 | return 0; |
508 | } | 509 | } |
509 | 510 | ||
510 | int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) | 511 | int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *cdev) |
511 | { | 512 | { |
512 | int ret = 0; | 513 | int ret = 0; |
513 | 514 | ||
514 | switch (dev->chip.usb_id) { | 515 | switch (cdev->chip.usb_id) { |
515 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 516 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
516 | ret = add_controls(ak1_controller, | 517 | ret = add_controls(ak1_controller, |
517 | ARRAY_SIZE(ak1_controller), dev); | 518 | ARRAY_SIZE(ak1_controller), cdev); |
518 | break; | 519 | break; |
519 | 520 | ||
520 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 521 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
521 | ret = add_controls(rk2_controller, | 522 | ret = add_controls(rk2_controller, |
522 | ARRAY_SIZE(rk2_controller), dev); | 523 | ARRAY_SIZE(rk2_controller), cdev); |
523 | break; | 524 | break; |
524 | 525 | ||
525 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
526 | ret = add_controls(rk3_controller, | 527 | ret = add_controls(rk3_controller, |
527 | ARRAY_SIZE(rk3_controller), dev); | 528 | ARRAY_SIZE(rk3_controller), cdev); |
528 | break; | 529 | break; |
529 | 530 | ||
530 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 531 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): |
531 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 532 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): |
532 | ret = add_controls(kore_controller, | 533 | ret = add_controls(kore_controller, |
533 | ARRAY_SIZE(kore_controller), dev); | 534 | ARRAY_SIZE(kore_controller), cdev); |
534 | break; | 535 | break; |
535 | 536 | ||
536 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 537 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
537 | ret = add_controls(a8dj_controller, | 538 | ret = add_controls(a8dj_controller, |
538 | ARRAY_SIZE(a8dj_controller), dev); | 539 | ARRAY_SIZE(a8dj_controller), cdev); |
539 | break; | 540 | break; |
540 | 541 | ||
541 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | 542 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
542 | ret = add_controls(a4dj_controller, | 543 | ret = add_controls(a4dj_controller, |
543 | ARRAY_SIZE(a4dj_controller), dev); | 544 | ARRAY_SIZE(a4dj_controller), cdev); |
544 | break; | 545 | break; |
545 | 546 | ||
546 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 547 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
547 | ret = add_controls(kontrolx1_controller, | 548 | ret = add_controls(kontrolx1_controller, |
548 | ARRAY_SIZE(kontrolx1_controller), dev); | 549 | ARRAY_SIZE(kontrolx1_controller), cdev); |
549 | break; | 550 | break; |
550 | 551 | ||
551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 552 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
552 | ret = add_controls(kontrols4_controller, | 553 | ret = add_controls(kontrols4_controller, |
553 | ARRAY_SIZE(kontrols4_controller), dev); | 554 | ARRAY_SIZE(kontrols4_controller), cdev); |
554 | break; | 555 | break; |
555 | } | 556 | } |
556 | 557 | ||
diff --git a/sound/usb/caiaq/control.h b/sound/usb/caiaq/control.h index 2e7ab1aa4fb3..501c4883aef6 100644 --- a/sound/usb/caiaq/control.h +++ b/sound/usb/caiaq/control.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #ifndef CAIAQ_CONTROL_H | 1 | #ifndef CAIAQ_CONTROL_H |
2 | #define CAIAQ_CONTROL_H | 2 | #define CAIAQ_CONTROL_H |
3 | 3 | ||
4 | int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev); | 4 | int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *cdev); |
5 | 5 | ||
6 | #endif /* CAIAQ_CONTROL_H */ | 6 | #endif /* CAIAQ_CONTROL_H */ |
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index e4d6dbb0342d..48b63ccc78c7 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
23 | #include <linux/device.h> | ||
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -158,67 +159,68 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
158 | static void usb_ep1_command_reply_dispatch (struct urb* urb) | 159 | static void usb_ep1_command_reply_dispatch (struct urb* urb) |
159 | { | 160 | { |
160 | int ret; | 161 | int ret; |
161 | struct snd_usb_caiaqdev *dev = urb->context; | 162 | struct device *dev = &urb->dev->dev; |
163 | struct snd_usb_caiaqdev *cdev = urb->context; | ||
162 | unsigned char *buf = urb->transfer_buffer; | 164 | unsigned char *buf = urb->transfer_buffer; |
163 | 165 | ||
164 | if (urb->status || !dev) { | 166 | if (urb->status || !cdev) { |
165 | log("received EP1 urb->status = %i\n", urb->status); | 167 | dev_warn(dev, "received EP1 urb->status = %i\n", urb->status); |
166 | return; | 168 | return; |
167 | } | 169 | } |
168 | 170 | ||
169 | switch(buf[0]) { | 171 | switch(buf[0]) { |
170 | case EP1_CMD_GET_DEVICE_INFO: | 172 | case EP1_CMD_GET_DEVICE_INFO: |
171 | memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec)); | 173 | memcpy(&cdev->spec, buf+1, sizeof(struct caiaq_device_spec)); |
172 | dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version); | 174 | cdev->spec.fw_version = le16_to_cpu(cdev->spec.fw_version); |
173 | debug("device spec (firmware %d): audio: %d in, %d out, " | 175 | dev_dbg(dev, "device spec (firmware %d): audio: %d in, %d out, " |
174 | "MIDI: %d in, %d out, data alignment %d\n", | 176 | "MIDI: %d in, %d out, data alignment %d\n", |
175 | dev->spec.fw_version, | 177 | cdev->spec.fw_version, |
176 | dev->spec.num_analog_audio_in, | 178 | cdev->spec.num_analog_audio_in, |
177 | dev->spec.num_analog_audio_out, | 179 | cdev->spec.num_analog_audio_out, |
178 | dev->spec.num_midi_in, | 180 | cdev->spec.num_midi_in, |
179 | dev->spec.num_midi_out, | 181 | cdev->spec.num_midi_out, |
180 | dev->spec.data_alignment); | 182 | cdev->spec.data_alignment); |
181 | 183 | ||
182 | dev->spec_received++; | 184 | cdev->spec_received++; |
183 | wake_up(&dev->ep1_wait_queue); | 185 | wake_up(&cdev->ep1_wait_queue); |
184 | break; | 186 | break; |
185 | case EP1_CMD_AUDIO_PARAMS: | 187 | case EP1_CMD_AUDIO_PARAMS: |
186 | dev->audio_parm_answer = buf[1]; | 188 | cdev->audio_parm_answer = buf[1]; |
187 | wake_up(&dev->ep1_wait_queue); | 189 | wake_up(&cdev->ep1_wait_queue); |
188 | break; | 190 | break; |
189 | case EP1_CMD_MIDI_READ: | 191 | case EP1_CMD_MIDI_READ: |
190 | snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); | 192 | snd_usb_caiaq_midi_handle_input(cdev, buf[1], buf + 3, buf[2]); |
191 | break; | 193 | break; |
192 | case EP1_CMD_READ_IO: | 194 | case EP1_CMD_READ_IO: |
193 | if (dev->chip.usb_id == | 195 | if (cdev->chip.usb_id == |
194 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { | 196 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) { |
195 | if (urb->actual_length > sizeof(dev->control_state)) | 197 | if (urb->actual_length > sizeof(cdev->control_state)) |
196 | urb->actual_length = sizeof(dev->control_state); | 198 | urb->actual_length = sizeof(cdev->control_state); |
197 | memcpy(dev->control_state, buf + 1, urb->actual_length); | 199 | memcpy(cdev->control_state, buf + 1, urb->actual_length); |
198 | wake_up(&dev->ep1_wait_queue); | 200 | wake_up(&cdev->ep1_wait_queue); |
199 | break; | 201 | break; |
200 | } | 202 | } |
201 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 203 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
202 | case EP1_CMD_READ_ERP: | 204 | case EP1_CMD_READ_ERP: |
203 | case EP1_CMD_READ_ANALOG: | 205 | case EP1_CMD_READ_ANALOG: |
204 | snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); | 206 | snd_usb_caiaq_input_dispatch(cdev, buf, urb->actual_length); |
205 | #endif | 207 | #endif |
206 | break; | 208 | break; |
207 | } | 209 | } |
208 | 210 | ||
209 | dev->ep1_in_urb.actual_length = 0; | 211 | cdev->ep1_in_urb.actual_length = 0; |
210 | ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC); | 212 | ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC); |
211 | if (ret < 0) | 213 | if (ret < 0) |
212 | log("unable to submit urb. OOM!?\n"); | 214 | dev_err(dev, "unable to submit urb. OOM!?\n"); |
213 | } | 215 | } |
214 | 216 | ||
215 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, | 217 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, |
216 | unsigned char command, | 218 | unsigned char command, |
217 | const unsigned char *buffer, | 219 | const unsigned char *buffer, |
218 | int len) | 220 | int len) |
219 | { | 221 | { |
220 | int actual_len; | 222 | int actual_len; |
221 | struct usb_device *usb_dev = dev->chip.dev; | 223 | struct usb_device *usb_dev = cdev->chip.dev; |
222 | 224 | ||
223 | if (!usb_dev) | 225 | if (!usb_dev) |
224 | return -EIO; | 226 | return -EIO; |
@@ -227,18 +229,19 @@ int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, | |||
227 | len = EP1_BUFSIZE - 1; | 229 | len = EP1_BUFSIZE - 1; |
228 | 230 | ||
229 | if (buffer && len > 0) | 231 | if (buffer && len > 0) |
230 | memcpy(dev->ep1_out_buf+1, buffer, len); | 232 | memcpy(cdev->ep1_out_buf+1, buffer, len); |
231 | 233 | ||
232 | dev->ep1_out_buf[0] = command; | 234 | cdev->ep1_out_buf[0] = command; |
233 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), | 235 | return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), |
234 | dev->ep1_out_buf, len+1, &actual_len, 200); | 236 | cdev->ep1_out_buf, len+1, &actual_len, 200); |
235 | } | 237 | } |
236 | 238 | ||
237 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | 239 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev, |
238 | int rate, int depth, int bpp) | 240 | int rate, int depth, int bpp) |
239 | { | 241 | { |
240 | int ret; | 242 | int ret; |
241 | char tmp[5]; | 243 | char tmp[5]; |
244 | struct device *dev = caiaqdev_to_dev(cdev); | ||
242 | 245 | ||
243 | switch (rate) { | 246 | switch (rate) { |
244 | case 44100: tmp[0] = SAMPLERATE_44100; break; | 247 | case 44100: tmp[0] = SAMPLERATE_44100; break; |
@@ -259,49 +262,50 @@ int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, | |||
259 | tmp[3] = bpp >> 8; | 262 | tmp[3] = bpp >> 8; |
260 | tmp[4] = 1; /* packets per microframe */ | 263 | tmp[4] = 1; /* packets per microframe */ |
261 | 264 | ||
262 | debug("setting audio params: %d Hz, %d bits, %d bpp\n", | 265 | dev_dbg(dev, "setting audio params: %d Hz, %d bits, %d bpp\n", |
263 | rate, depth, bpp); | 266 | rate, depth, bpp); |
264 | 267 | ||
265 | dev->audio_parm_answer = -1; | 268 | cdev->audio_parm_answer = -1; |
266 | ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS, | 269 | ret = snd_usb_caiaq_send_command(cdev, EP1_CMD_AUDIO_PARAMS, |
267 | tmp, sizeof(tmp)); | 270 | tmp, sizeof(tmp)); |
268 | 271 | ||
269 | if (ret) | 272 | if (ret) |
270 | return ret; | 273 | return ret; |
271 | 274 | ||
272 | if (!wait_event_timeout(dev->ep1_wait_queue, | 275 | if (!wait_event_timeout(cdev->ep1_wait_queue, |
273 | dev->audio_parm_answer >= 0, HZ)) | 276 | cdev->audio_parm_answer >= 0, HZ)) |
274 | return -EPIPE; | 277 | return -EPIPE; |
275 | 278 | ||
276 | if (dev->audio_parm_answer != 1) | 279 | if (cdev->audio_parm_answer != 1) |
277 | debug("unable to set the device's audio params\n"); | 280 | dev_dbg(dev, "unable to set the device's audio params\n"); |
278 | else | 281 | else |
279 | dev->bpp = bpp; | 282 | cdev->bpp = bpp; |
280 | 283 | ||
281 | return dev->audio_parm_answer == 1 ? 0 : -EINVAL; | 284 | return cdev->audio_parm_answer == 1 ? 0 : -EINVAL; |
282 | } | 285 | } |
283 | 286 | ||
284 | int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *dev, | 287 | int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *cdev, |
285 | int digital, int analog, int erp) | 288 | int digital, int analog, int erp) |
286 | { | 289 | { |
287 | char tmp[3] = { digital, analog, erp }; | 290 | char tmp[3] = { digital, analog, erp }; |
288 | return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG, | 291 | return snd_usb_caiaq_send_command(cdev, EP1_CMD_AUTO_MSG, |
289 | tmp, sizeof(tmp)); | 292 | tmp, sizeof(tmp)); |
290 | } | 293 | } |
291 | 294 | ||
292 | static void setup_card(struct snd_usb_caiaqdev *dev) | 295 | static void setup_card(struct snd_usb_caiaqdev *cdev) |
293 | { | 296 | { |
294 | int ret; | 297 | int ret; |
295 | char val[4]; | 298 | char val[4]; |
299 | struct device *dev = caiaqdev_to_dev(cdev); | ||
296 | 300 | ||
297 | /* device-specific startup specials */ | 301 | /* device-specific startup specials */ |
298 | switch (dev->chip.usb_id) { | 302 | switch (cdev->chip.usb_id) { |
299 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 303 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
300 | /* RigKontrol2 - display centered dash ('-') */ | 304 | /* RigKontrol2 - display centered dash ('-') */ |
301 | val[0] = 0x00; | 305 | val[0] = 0x00; |
302 | val[1] = 0x00; | 306 | val[1] = 0x00; |
303 | val[2] = 0x01; | 307 | val[2] = 0x01; |
304 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3); | 308 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 3); |
305 | break; | 309 | break; |
306 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 310 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
307 | /* RigKontrol2 - display two centered dashes ('--') */ | 311 | /* RigKontrol2 - display two centered dashes ('--') */ |
@@ -309,69 +313,69 @@ static void setup_card(struct snd_usb_caiaqdev *dev) | |||
309 | val[1] = 0x40; | 313 | val[1] = 0x40; |
310 | val[2] = 0x40; | 314 | val[2] = 0x40; |
311 | val[3] = 0x00; | 315 | val[3] = 0x00; |
312 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4); | 316 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 4); |
313 | break; | 317 | break; |
314 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 318 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
315 | /* Audio Kontrol 1 - make USB-LED stop blinking */ | 319 | /* Audio Kontrol 1 - make USB-LED stop blinking */ |
316 | val[0] = 0x00; | 320 | val[0] = 0x00; |
317 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1); | 321 | snd_usb_caiaq_send_command(cdev, EP1_CMD_WRITE_IO, val, 1); |
318 | break; | 322 | break; |
319 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 323 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
320 | /* Audio 8 DJ - trigger read of current settings */ | 324 | /* Audio 8 DJ - trigger read of current settings */ |
321 | dev->control_state[0] = 0xff; | 325 | cdev->control_state[0] = 0xff; |
322 | snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0); | 326 | snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 0); |
323 | snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0); | 327 | snd_usb_caiaq_send_command(cdev, EP1_CMD_READ_IO, NULL, 0); |
324 | 328 | ||
325 | if (!wait_event_timeout(dev->ep1_wait_queue, | 329 | if (!wait_event_timeout(cdev->ep1_wait_queue, |
326 | dev->control_state[0] != 0xff, HZ)) | 330 | cdev->control_state[0] != 0xff, HZ)) |
327 | return; | 331 | return; |
328 | 332 | ||
329 | /* fix up some defaults */ | 333 | /* fix up some defaults */ |
330 | if ((dev->control_state[1] != 2) || | 334 | if ((cdev->control_state[1] != 2) || |
331 | (dev->control_state[2] != 3) || | 335 | (cdev->control_state[2] != 3) || |
332 | (dev->control_state[4] != 2)) { | 336 | (cdev->control_state[4] != 2)) { |
333 | dev->control_state[1] = 2; | 337 | cdev->control_state[1] = 2; |
334 | dev->control_state[2] = 3; | 338 | cdev->control_state[2] = 3; |
335 | dev->control_state[4] = 2; | 339 | cdev->control_state[4] = 2; |
336 | snd_usb_caiaq_send_command(dev, | 340 | snd_usb_caiaq_send_command(cdev, |
337 | EP1_CMD_WRITE_IO, dev->control_state, 6); | 341 | EP1_CMD_WRITE_IO, cdev->control_state, 6); |
338 | } | 342 | } |
339 | 343 | ||
340 | break; | 344 | break; |
341 | } | 345 | } |
342 | 346 | ||
343 | if (dev->spec.num_analog_audio_out + | 347 | if (cdev->spec.num_analog_audio_out + |
344 | dev->spec.num_analog_audio_in + | 348 | cdev->spec.num_analog_audio_in + |
345 | dev->spec.num_digital_audio_out + | 349 | cdev->spec.num_digital_audio_out + |
346 | dev->spec.num_digital_audio_in > 0) { | 350 | cdev->spec.num_digital_audio_in > 0) { |
347 | ret = snd_usb_caiaq_audio_init(dev); | 351 | ret = snd_usb_caiaq_audio_init(cdev); |
348 | if (ret < 0) | 352 | if (ret < 0) |
349 | log("Unable to set up audio system (ret=%d)\n", ret); | 353 | dev_err(dev, "Unable to set up audio system (ret=%d)\n", ret); |
350 | } | 354 | } |
351 | 355 | ||
352 | if (dev->spec.num_midi_in + | 356 | if (cdev->spec.num_midi_in + |
353 | dev->spec.num_midi_out > 0) { | 357 | cdev->spec.num_midi_out > 0) { |
354 | ret = snd_usb_caiaq_midi_init(dev); | 358 | ret = snd_usb_caiaq_midi_init(cdev); |
355 | if (ret < 0) | 359 | if (ret < 0) |
356 | log("Unable to set up MIDI system (ret=%d)\n", ret); | 360 | dev_err(dev, "Unable to set up MIDI system (ret=%d)\n", ret); |
357 | } | 361 | } |
358 | 362 | ||
359 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 363 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
360 | ret = snd_usb_caiaq_input_init(dev); | 364 | ret = snd_usb_caiaq_input_init(cdev); |
361 | if (ret < 0) | 365 | if (ret < 0) |
362 | log("Unable to set up input system (ret=%d)\n", ret); | 366 | dev_err(dev, "Unable to set up input system (ret=%d)\n", ret); |
363 | #endif | 367 | #endif |
364 | 368 | ||
365 | /* finally, register the card and all its sub-instances */ | 369 | /* finally, register the card and all its sub-instances */ |
366 | ret = snd_card_register(dev->chip.card); | 370 | ret = snd_card_register(cdev->chip.card); |
367 | if (ret < 0) { | 371 | if (ret < 0) { |
368 | log("snd_card_register() returned %d\n", ret); | 372 | dev_err(dev, "snd_card_register() returned %d\n", ret); |
369 | snd_card_free(dev->chip.card); | 373 | snd_card_free(cdev->chip.card); |
370 | } | 374 | } |
371 | 375 | ||
372 | ret = snd_usb_caiaq_control_init(dev); | 376 | ret = snd_usb_caiaq_control_init(cdev); |
373 | if (ret < 0) | 377 | if (ret < 0) |
374 | log("Unable to set up control system (ret=%d)\n", ret); | 378 | dev_err(dev, "Unable to set up control system (ret=%d)\n", ret); |
375 | } | 379 | } |
376 | 380 | ||
377 | static int create_card(struct usb_device *usb_dev, | 381 | static int create_card(struct usb_device *usb_dev, |
@@ -381,7 +385,7 @@ static int create_card(struct usb_device *usb_dev, | |||
381 | int devnum; | 385 | int devnum; |
382 | int err; | 386 | int err; |
383 | struct snd_card *card; | 387 | struct snd_card *card; |
384 | struct snd_usb_caiaqdev *dev; | 388 | struct snd_usb_caiaqdev *cdev; |
385 | 389 | ||
386 | for (devnum = 0; devnum < SNDRV_CARDS; devnum++) | 390 | for (devnum = 0; devnum < SNDRV_CARDS; devnum++) |
387 | if (enable[devnum] && !snd_card_used[devnum]) | 391 | if (enable[devnum] && !snd_card_used[devnum]) |
@@ -395,65 +399,66 @@ static int create_card(struct usb_device *usb_dev, | |||
395 | if (err < 0) | 399 | if (err < 0) |
396 | return err; | 400 | return err; |
397 | 401 | ||
398 | dev = caiaqdev(card); | 402 | cdev = caiaqdev(card); |
399 | dev->chip.dev = usb_dev; | 403 | cdev->chip.dev = usb_dev; |
400 | dev->chip.card = card; | 404 | cdev->chip.card = card; |
401 | dev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), | 405 | cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor), |
402 | le16_to_cpu(usb_dev->descriptor.idProduct)); | 406 | le16_to_cpu(usb_dev->descriptor.idProduct)); |
403 | spin_lock_init(&dev->spinlock); | 407 | spin_lock_init(&cdev->spinlock); |
404 | snd_card_set_dev(card, &intf->dev); | 408 | snd_card_set_dev(card, &intf->dev); |
405 | 409 | ||
406 | *cardp = card; | 410 | *cardp = card; |
407 | return 0; | 411 | return 0; |
408 | } | 412 | } |
409 | 413 | ||
410 | static int init_card(struct snd_usb_caiaqdev *dev) | 414 | static int init_card(struct snd_usb_caiaqdev *cdev) |
411 | { | 415 | { |
412 | char *c, usbpath[32]; | 416 | char *c, usbpath[32]; |
413 | struct usb_device *usb_dev = dev->chip.dev; | 417 | struct usb_device *usb_dev = cdev->chip.dev; |
414 | struct snd_card *card = dev->chip.card; | 418 | struct snd_card *card = cdev->chip.card; |
419 | struct device *dev = caiaqdev_to_dev(cdev); | ||
415 | int err, len; | 420 | int err, len; |
416 | 421 | ||
417 | if (usb_set_interface(usb_dev, 0, 1) != 0) { | 422 | if (usb_set_interface(usb_dev, 0, 1) != 0) { |
418 | log("can't set alt interface.\n"); | 423 | dev_err(dev, "can't set alt interface.\n"); |
419 | return -EIO; | 424 | return -EIO; |
420 | } | 425 | } |
421 | 426 | ||
422 | usb_init_urb(&dev->ep1_in_urb); | 427 | usb_init_urb(&cdev->ep1_in_urb); |
423 | usb_init_urb(&dev->midi_out_urb); | 428 | usb_init_urb(&cdev->midi_out_urb); |
424 | 429 | ||
425 | usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, | 430 | usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev, |
426 | usb_rcvbulkpipe(usb_dev, 0x1), | 431 | usb_rcvbulkpipe(usb_dev, 0x1), |
427 | dev->ep1_in_buf, EP1_BUFSIZE, | 432 | cdev->ep1_in_buf, EP1_BUFSIZE, |
428 | usb_ep1_command_reply_dispatch, dev); | 433 | usb_ep1_command_reply_dispatch, cdev); |
429 | 434 | ||
430 | usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, | 435 | usb_fill_bulk_urb(&cdev->midi_out_urb, usb_dev, |
431 | usb_sndbulkpipe(usb_dev, 0x1), | 436 | usb_sndbulkpipe(usb_dev, 0x1), |
432 | dev->midi_out_buf, EP1_BUFSIZE, | 437 | cdev->midi_out_buf, EP1_BUFSIZE, |
433 | snd_usb_caiaq_midi_output_done, dev); | 438 | snd_usb_caiaq_midi_output_done, cdev); |
434 | 439 | ||
435 | init_waitqueue_head(&dev->ep1_wait_queue); | 440 | init_waitqueue_head(&cdev->ep1_wait_queue); |
436 | init_waitqueue_head(&dev->prepare_wait_queue); | 441 | init_waitqueue_head(&cdev->prepare_wait_queue); |
437 | 442 | ||
438 | if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) | 443 | if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0) |
439 | return -EIO; | 444 | return -EIO; |
440 | 445 | ||
441 | err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); | 446 | err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); |
442 | if (err) | 447 | if (err) |
443 | return err; | 448 | return err; |
444 | 449 | ||
445 | if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ)) | 450 | if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) |
446 | return -ENODEV; | 451 | return -ENODEV; |
447 | 452 | ||
448 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, | 453 | usb_string(usb_dev, usb_dev->descriptor.iManufacturer, |
449 | dev->vendor_name, CAIAQ_USB_STR_LEN); | 454 | cdev->vendor_name, CAIAQ_USB_STR_LEN); |
450 | 455 | ||
451 | usb_string(usb_dev, usb_dev->descriptor.iProduct, | 456 | usb_string(usb_dev, usb_dev->descriptor.iProduct, |
452 | dev->product_name, CAIAQ_USB_STR_LEN); | 457 | cdev->product_name, CAIAQ_USB_STR_LEN); |
453 | 458 | ||
454 | strlcpy(card->driver, MODNAME, sizeof(card->driver)); | 459 | strlcpy(card->driver, MODNAME, sizeof(card->driver)); |
455 | strlcpy(card->shortname, dev->product_name, sizeof(card->shortname)); | 460 | strlcpy(card->shortname, cdev->product_name, sizeof(card->shortname)); |
456 | strlcpy(card->mixername, dev->product_name, sizeof(card->mixername)); | 461 | strlcpy(card->mixername, cdev->product_name, sizeof(card->mixername)); |
457 | 462 | ||
458 | /* if the id was not passed as module option, fill it with a shortened | 463 | /* if the id was not passed as module option, fill it with a shortened |
459 | * version of the product string which does not contain any | 464 | * version of the product string which does not contain any |
@@ -473,11 +478,10 @@ static int init_card(struct snd_usb_caiaqdev *dev) | |||
473 | } | 478 | } |
474 | 479 | ||
475 | usb_make_path(usb_dev, usbpath, sizeof(usbpath)); | 480 | usb_make_path(usb_dev, usbpath, sizeof(usbpath)); |
476 | snprintf(card->longname, sizeof(card->longname), | 481 | snprintf(card->longname, sizeof(card->longname), "%s %s (%s)", |
477 | "%s %s (%s)", | 482 | cdev->vendor_name, cdev->product_name, usbpath); |
478 | dev->vendor_name, dev->product_name, usbpath); | ||
479 | 483 | ||
480 | setup_card(dev); | 484 | setup_card(cdev); |
481 | return 0; | 485 | return 0; |
482 | } | 486 | } |
483 | 487 | ||
@@ -486,9 +490,9 @@ static int snd_probe(struct usb_interface *intf, | |||
486 | { | 490 | { |
487 | int ret; | 491 | int ret; |
488 | struct snd_card *card = NULL; | 492 | struct snd_card *card = NULL; |
489 | struct usb_device *device = interface_to_usbdev(intf); | 493 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
490 | 494 | ||
491 | ret = create_card(device, intf, &card); | 495 | ret = create_card(usb_dev, intf, &card); |
492 | 496 | ||
493 | if (ret < 0) | 497 | if (ret < 0) |
494 | return ret; | 498 | return ret; |
@@ -496,7 +500,7 @@ static int snd_probe(struct usb_interface *intf, | |||
496 | usb_set_intfdata(intf, card); | 500 | usb_set_intfdata(intf, card); |
497 | ret = init_card(caiaqdev(card)); | 501 | ret = init_card(caiaqdev(card)); |
498 | if (ret < 0) { | 502 | if (ret < 0) { |
499 | log("unable to init card! (ret=%d)\n", ret); | 503 | dev_err(&usb_dev->dev, "unable to init card! (ret=%d)\n", ret); |
500 | snd_card_free(card); | 504 | snd_card_free(card); |
501 | return ret; | 505 | return ret; |
502 | } | 506 | } |
@@ -506,24 +510,25 @@ static int snd_probe(struct usb_interface *intf, | |||
506 | 510 | ||
507 | static void snd_disconnect(struct usb_interface *intf) | 511 | static void snd_disconnect(struct usb_interface *intf) |
508 | { | 512 | { |
509 | struct snd_usb_caiaqdev *dev; | ||
510 | struct snd_card *card = usb_get_intfdata(intf); | 513 | struct snd_card *card = usb_get_intfdata(intf); |
511 | 514 | struct device *dev = intf->usb_dev; | |
512 | debug("%s(%p)\n", __func__, intf); | 515 | struct snd_usb_caiaqdev *cdev; |
513 | 516 | ||
514 | if (!card) | 517 | if (!card) |
515 | return; | 518 | return; |
516 | 519 | ||
517 | dev = caiaqdev(card); | 520 | cdev = caiaqdev(card); |
521 | dev_dbg(dev, "%s(%p)\n", __func__, intf); | ||
522 | |||
518 | snd_card_disconnect(card); | 523 | snd_card_disconnect(card); |
519 | 524 | ||
520 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT | 525 | #ifdef CONFIG_SND_USB_CAIAQ_INPUT |
521 | snd_usb_caiaq_input_free(dev); | 526 | snd_usb_caiaq_input_free(cdev); |
522 | #endif | 527 | #endif |
523 | snd_usb_caiaq_audio_free(dev); | 528 | snd_usb_caiaq_audio_free(cdev); |
524 | 529 | ||
525 | usb_kill_urb(&dev->ep1_in_urb); | 530 | usb_kill_urb(&cdev->ep1_in_urb); |
526 | usb_kill_urb(&dev->midi_out_urb); | 531 | usb_kill_urb(&cdev->midi_out_urb); |
527 | 532 | ||
528 | snd_card_free(card); | 533 | snd_card_free(card); |
529 | usb_reset_device(interface_to_usbdev(intf)); | 534 | usb_reset_device(interface_to_usbdev(intf)); |
@@ -539,4 +544,3 @@ static struct usb_driver snd_usb_driver = { | |||
539 | }; | 544 | }; |
540 | 545 | ||
541 | module_usb_driver(snd_usb_driver); | 546 | module_usb_driver(snd_usb_driver); |
542 | |||
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 562b0bff9c41..ad102fac6942 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -25,16 +25,7 @@ | |||
25 | #define CAIAQ_USB_STR_LEN 0xff | 25 | #define CAIAQ_USB_STR_LEN 0xff |
26 | #define MAX_STREAMS 32 | 26 | #define MAX_STREAMS 32 |
27 | 27 | ||
28 | //#define SND_USB_CAIAQ_DEBUG | ||
29 | |||
30 | #define MODNAME "snd-usb-caiaq" | 28 | #define MODNAME "snd-usb-caiaq" |
31 | #define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x) | ||
32 | |||
33 | #ifdef SND_USB_CAIAQ_DEBUG | ||
34 | #define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x) | ||
35 | #else | ||
36 | #define debug(x...) do { } while(0) | ||
37 | #endif | ||
38 | 29 | ||
39 | #define EP1_CMD_GET_DEVICE_INFO 0x1 | 30 | #define EP1_CMD_GET_DEVICE_INFO 0x1 |
40 | #define EP1_CMD_READ_ERP 0x2 | 31 | #define EP1_CMD_READ_ERP 0x2 |
@@ -124,15 +115,16 @@ struct snd_usb_caiaqdev { | |||
124 | }; | 115 | }; |
125 | 116 | ||
126 | struct snd_usb_caiaq_cb_info { | 117 | struct snd_usb_caiaq_cb_info { |
127 | struct snd_usb_caiaqdev *dev; | 118 | struct snd_usb_caiaqdev *cdev; |
128 | int index; | 119 | int index; |
129 | }; | 120 | }; |
130 | 121 | ||
131 | #define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data) | 122 | #define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data) |
123 | #define caiaqdev_to_dev(d) (d->chip.card->dev) | ||
132 | 124 | ||
133 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp); | 125 | int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *cdev, int rate, int depth, int bbp); |
134 | int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp); | 126 | int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *cdev, int digital, int analog, int erp); |
135 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev, | 127 | int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *cdev, |
136 | unsigned char command, | 128 | unsigned char command, |
137 | const unsigned char *buffer, | 129 | const unsigned char *buffer, |
138 | int len); | 130 | int len); |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 26a121b42c3c..4b3fb91deecd 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | ||
19 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
@@ -199,55 +200,55 @@ static unsigned int decode_erp(unsigned char a, unsigned char b) | |||
199 | #undef HIGH_PEAK | 200 | #undef HIGH_PEAK |
200 | #undef LOW_PEAK | 201 | #undef LOW_PEAK |
201 | 202 | ||
202 | static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev, | 203 | static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *cdev, |
203 | int axis, const unsigned char *buf, | 204 | int axis, const unsigned char *buf, |
204 | int offset) | 205 | int offset) |
205 | { | 206 | { |
206 | input_report_abs(dev->input_dev, axis, | 207 | input_report_abs(cdev->input_dev, axis, |
207 | (buf[offset * 2] << 8) | buf[offset * 2 + 1]); | 208 | (buf[offset * 2] << 8) | buf[offset * 2 + 1]); |
208 | } | 209 | } |
209 | 210 | ||
210 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, | 211 | static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *cdev, |
211 | const unsigned char *buf, | 212 | const unsigned char *buf, |
212 | unsigned int len) | 213 | unsigned int len) |
213 | { | 214 | { |
214 | struct input_dev *input_dev = dev->input_dev; | 215 | struct input_dev *input_dev = cdev->input_dev; |
215 | 216 | ||
216 | switch (dev->chip.usb_id) { | 217 | switch (cdev->chip.usb_id) { |
217 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 218 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
218 | snd_caiaq_input_report_abs(dev, ABS_X, buf, 2); | 219 | snd_caiaq_input_report_abs(cdev, ABS_X, buf, 2); |
219 | snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0); | 220 | snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 0); |
220 | snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1); | 221 | snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 1); |
221 | break; | 222 | break; |
222 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 223 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
223 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 224 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): |
224 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 225 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): |
225 | snd_caiaq_input_report_abs(dev, ABS_X, buf, 0); | 226 | snd_caiaq_input_report_abs(cdev, ABS_X, buf, 0); |
226 | snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1); | 227 | snd_caiaq_input_report_abs(cdev, ABS_Y, buf, 1); |
227 | snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2); | 228 | snd_caiaq_input_report_abs(cdev, ABS_Z, buf, 2); |
228 | break; | 229 | break; |
229 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 230 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
230 | snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4); | 231 | snd_caiaq_input_report_abs(cdev, ABS_HAT0X, buf, 4); |
231 | snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2); | 232 | snd_caiaq_input_report_abs(cdev, ABS_HAT0Y, buf, 2); |
232 | snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6); | 233 | snd_caiaq_input_report_abs(cdev, ABS_HAT1X, buf, 6); |
233 | snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1); | 234 | snd_caiaq_input_report_abs(cdev, ABS_HAT1Y, buf, 1); |
234 | snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7); | 235 | snd_caiaq_input_report_abs(cdev, ABS_HAT2X, buf, 7); |
235 | snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0); | 236 | snd_caiaq_input_report_abs(cdev, ABS_HAT2Y, buf, 0); |
236 | snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5); | 237 | snd_caiaq_input_report_abs(cdev, ABS_HAT3X, buf, 5); |
237 | snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3); | 238 | snd_caiaq_input_report_abs(cdev, ABS_HAT3Y, buf, 3); |
238 | break; | 239 | break; |
239 | } | 240 | } |
240 | 241 | ||
241 | input_sync(input_dev); | 242 | input_sync(input_dev); |
242 | } | 243 | } |
243 | 244 | ||
244 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | 245 | static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *cdev, |
245 | const char *buf, unsigned int len) | 246 | const char *buf, unsigned int len) |
246 | { | 247 | { |
247 | struct input_dev *input_dev = dev->input_dev; | 248 | struct input_dev *input_dev = cdev->input_dev; |
248 | int i; | 249 | int i; |
249 | 250 | ||
250 | switch (dev->chip.usb_id) { | 251 | switch (cdev->chip.usb_id) { |
251 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 252 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
252 | i = decode_erp(buf[0], buf[1]); | 253 | i = decode_erp(buf[0], buf[1]); |
253 | input_report_abs(input_dev, ABS_X, i); | 254 | input_report_abs(input_dev, ABS_X, i); |
@@ -299,10 +300,10 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | |||
299 | } | 300 | } |
300 | } | 301 | } |
301 | 302 | ||
302 | static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | 303 | static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *cdev, |
303 | unsigned char *buf, unsigned int len) | 304 | unsigned char *buf, unsigned int len) |
304 | { | 305 | { |
305 | struct input_dev *input_dev = dev->input_dev; | 306 | struct input_dev *input_dev = cdev->input_dev; |
306 | unsigned short *keycode = input_dev->keycode; | 307 | unsigned short *keycode = input_dev->keycode; |
307 | int i; | 308 | int i; |
308 | 309 | ||
@@ -317,17 +318,17 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | |||
317 | input_report_key(input_dev, keycode[i], | 318 | input_report_key(input_dev, keycode[i], |
318 | buf[i / 8] & (1 << (i % 8))); | 319 | buf[i / 8] & (1 << (i % 8))); |
319 | 320 | ||
320 | switch (dev->chip.usb_id) { | 321 | switch (cdev->chip.usb_id) { |
321 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 322 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): |
322 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 323 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): |
323 | input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); | 324 | input_report_abs(cdev->input_dev, ABS_MISC, 255 - buf[4]); |
324 | break; | 325 | break; |
325 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 326 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
326 | /* rotary encoders */ | 327 | /* rotary encoders */ |
327 | input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf); | 328 | input_report_abs(cdev->input_dev, ABS_X, buf[5] & 0xf); |
328 | input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4); | 329 | input_report_abs(cdev->input_dev, ABS_Y, buf[5] >> 4); |
329 | input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf); | 330 | input_report_abs(cdev->input_dev, ABS_Z, buf[6] & 0xf); |
330 | input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4); | 331 | input_report_abs(cdev->input_dev, ABS_MISC, buf[6] >> 4); |
331 | break; | 332 | break; |
332 | } | 333 | } |
333 | 334 | ||
@@ -336,10 +337,12 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, | |||
336 | 337 | ||
337 | #define TKS4_MSGBLOCK_SIZE 16 | 338 | #define TKS4_MSGBLOCK_SIZE 16 |
338 | 339 | ||
339 | static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | 340 | static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *cdev, |
340 | const unsigned char *buf, | 341 | const unsigned char *buf, |
341 | unsigned int len) | 342 | unsigned int len) |
342 | { | 343 | { |
344 | struct device *dev = caiaqdev_to_dev(cdev); | ||
345 | |||
343 | while (len) { | 346 | while (len) { |
344 | unsigned int i, block_id = (buf[0] << 8) | buf[1]; | 347 | unsigned int i, block_id = (buf[0] << 8) | buf[1]; |
345 | 348 | ||
@@ -347,126 +350,126 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | |||
347 | case 0: | 350 | case 0: |
348 | /* buttons */ | 351 | /* buttons */ |
349 | for (i = 0; i < KONTROLS4_BUTTONS; i++) | 352 | for (i = 0; i < KONTROLS4_BUTTONS; i++) |
350 | input_report_key(dev->input_dev, KONTROLS4_BUTTON(i), | 353 | input_report_key(cdev->input_dev, KONTROLS4_BUTTON(i), |
351 | (buf[4 + (i / 8)] >> (i % 8)) & 1); | 354 | (buf[4 + (i / 8)] >> (i % 8)) & 1); |
352 | break; | 355 | break; |
353 | 356 | ||
354 | case 1: | 357 | case 1: |
355 | /* left wheel */ | 358 | /* left wheel */ |
356 | input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8)); | 359 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8)); |
357 | /* right wheel */ | 360 | /* right wheel */ |
358 | input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8)); | 361 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8)); |
359 | 362 | ||
360 | /* rotary encoders */ | 363 | /* rotary encoders */ |
361 | input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf); | 364 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf); |
362 | input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4); | 365 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4); |
363 | input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf); | 366 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf); |
364 | input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4); | 367 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4); |
365 | input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf); | 368 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf); |
366 | input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4); | 369 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4); |
367 | input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf); | 370 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf); |
368 | input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4); | 371 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4); |
369 | input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf); | 372 | input_report_abs(cdev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf); |
370 | 373 | ||
371 | break; | 374 | break; |
372 | case 2: | 375 | case 2: |
373 | /* Volume Fader Channel D */ | 376 | /* Volume Fader Channel D */ |
374 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1); | 377 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(0), buf, 1); |
375 | /* Volume Fader Channel B */ | 378 | /* Volume Fader Channel B */ |
376 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2); | 379 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(1), buf, 2); |
377 | /* Volume Fader Channel A */ | 380 | /* Volume Fader Channel A */ |
378 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3); | 381 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(2), buf, 3); |
379 | /* Volume Fader Channel C */ | 382 | /* Volume Fader Channel C */ |
380 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4); | 383 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(3), buf, 4); |
381 | /* Loop Volume */ | 384 | /* Loop Volume */ |
382 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6); | 385 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(4), buf, 6); |
383 | /* Crossfader */ | 386 | /* Crossfader */ |
384 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7); | 387 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(7), buf, 7); |
385 | 388 | ||
386 | break; | 389 | break; |
387 | 390 | ||
388 | case 3: | 391 | case 3: |
389 | /* Tempo Fader R */ | 392 | /* Tempo Fader R */ |
390 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3); | 393 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(6), buf, 3); |
391 | /* Tempo Fader L */ | 394 | /* Tempo Fader L */ |
392 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4); | 395 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(5), buf, 4); |
393 | /* Mic Volume */ | 396 | /* Mic Volume */ |
394 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6); | 397 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(8), buf, 6); |
395 | /* Cue Mix */ | 398 | /* Cue Mix */ |
396 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7); | 399 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(9), buf, 7); |
397 | 400 | ||
398 | break; | 401 | break; |
399 | 402 | ||
400 | case 4: | 403 | case 4: |
401 | /* Wheel distance sensor L */ | 404 | /* Wheel distance sensor L */ |
402 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1); | 405 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(10), buf, 1); |
403 | /* Wheel distance sensor R */ | 406 | /* Wheel distance sensor R */ |
404 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2); | 407 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(11), buf, 2); |
405 | /* Channel D EQ - Filter */ | 408 | /* Channel D EQ - Filter */ |
406 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3); | 409 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(12), buf, 3); |
407 | /* Channel D EQ - Low */ | 410 | /* Channel D EQ - Low */ |
408 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4); | 411 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(13), buf, 4); |
409 | /* Channel D EQ - Mid */ | 412 | /* Channel D EQ - Mid */ |
410 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5); | 413 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(14), buf, 5); |
411 | /* Channel D EQ - Hi */ | 414 | /* Channel D EQ - Hi */ |
412 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6); | 415 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(15), buf, 6); |
413 | /* FX2 - dry/wet */ | 416 | /* FX2 - dry/wet */ |
414 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7); | 417 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(16), buf, 7); |
415 | 418 | ||
416 | break; | 419 | break; |
417 | 420 | ||
418 | case 5: | 421 | case 5: |
419 | /* FX2 - 1 */ | 422 | /* FX2 - 1 */ |
420 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1); | 423 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(17), buf, 1); |
421 | /* FX2 - 2 */ | 424 | /* FX2 - 2 */ |
422 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2); | 425 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(18), buf, 2); |
423 | /* FX2 - 3 */ | 426 | /* FX2 - 3 */ |
424 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3); | 427 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(19), buf, 3); |
425 | /* Channel B EQ - Filter */ | 428 | /* Channel B EQ - Filter */ |
426 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4); | 429 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(20), buf, 4); |
427 | /* Channel B EQ - Low */ | 430 | /* Channel B EQ - Low */ |
428 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5); | 431 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(21), buf, 5); |
429 | /* Channel B EQ - Mid */ | 432 | /* Channel B EQ - Mid */ |
430 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6); | 433 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(22), buf, 6); |
431 | /* Channel B EQ - Hi */ | 434 | /* Channel B EQ - Hi */ |
432 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7); | 435 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(23), buf, 7); |
433 | 436 | ||
434 | break; | 437 | break; |
435 | 438 | ||
436 | case 6: | 439 | case 6: |
437 | /* Channel A EQ - Filter */ | 440 | /* Channel A EQ - Filter */ |
438 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1); | 441 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(24), buf, 1); |
439 | /* Channel A EQ - Low */ | 442 | /* Channel A EQ - Low */ |
440 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2); | 443 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(25), buf, 2); |
441 | /* Channel A EQ - Mid */ | 444 | /* Channel A EQ - Mid */ |
442 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3); | 445 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(26), buf, 3); |
443 | /* Channel A EQ - Hi */ | 446 | /* Channel A EQ - Hi */ |
444 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4); | 447 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(27), buf, 4); |
445 | /* Channel C EQ - Filter */ | 448 | /* Channel C EQ - Filter */ |
446 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5); | 449 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(28), buf, 5); |
447 | /* Channel C EQ - Low */ | 450 | /* Channel C EQ - Low */ |
448 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6); | 451 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(29), buf, 6); |
449 | /* Channel C EQ - Mid */ | 452 | /* Channel C EQ - Mid */ |
450 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7); | 453 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(30), buf, 7); |
451 | 454 | ||
452 | break; | 455 | break; |
453 | 456 | ||
454 | case 7: | 457 | case 7: |
455 | /* Channel C EQ - Hi */ | 458 | /* Channel C EQ - Hi */ |
456 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1); | 459 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(31), buf, 1); |
457 | /* FX1 - wet/dry */ | 460 | /* FX1 - wet/dry */ |
458 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2); | 461 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(32), buf, 2); |
459 | /* FX1 - 1 */ | 462 | /* FX1 - 1 */ |
460 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3); | 463 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(33), buf, 3); |
461 | /* FX1 - 2 */ | 464 | /* FX1 - 2 */ |
462 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4); | 465 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(34), buf, 4); |
463 | /* FX1 - 3 */ | 466 | /* FX1 - 3 */ |
464 | snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5); | 467 | snd_caiaq_input_report_abs(cdev, KONTROLS4_ABS(35), buf, 5); |
465 | 468 | ||
466 | break; | 469 | break; |
467 | 470 | ||
468 | default: | 471 | default: |
469 | debug("%s(): bogus block (id %d)\n", | 472 | dev_dbg(dev, "%s(): bogus block (id %d)\n", |
470 | __func__, block_id); | 473 | __func__, block_id); |
471 | return; | 474 | return; |
472 | } | 475 | } |
@@ -475,81 +478,82 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | |||
475 | buf += TKS4_MSGBLOCK_SIZE; | 478 | buf += TKS4_MSGBLOCK_SIZE; |
476 | } | 479 | } |
477 | 480 | ||
478 | input_sync(dev->input_dev); | 481 | input_sync(cdev->input_dev); |
479 | } | 482 | } |
480 | 483 | ||
481 | #define MASCHINE_MSGBLOCK_SIZE 2 | 484 | #define MASCHINE_MSGBLOCK_SIZE 2 |
482 | 485 | ||
483 | static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev, | 486 | static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *cdev, |
484 | const unsigned char *buf, | 487 | const unsigned char *buf, |
485 | unsigned int len) | 488 | unsigned int len) |
486 | { | 489 | { |
487 | unsigned int i, pad_id; | 490 | unsigned int i, pad_id; |
488 | uint16_t pressure; | 491 | __le16 *pressure = (__le16 *) buf; |
489 | 492 | ||
490 | for (i = 0; i < MASCHINE_PADS; i++) { | 493 | for (i = 0; i < MASCHINE_PADS; i++) { |
491 | pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]); | 494 | pad_id = le16_to_cpu(*pressure) >> 12; |
492 | pad_id = pressure >> 12; | 495 | input_report_abs(cdev->input_dev, MASCHINE_PAD(pad_id), |
493 | 496 | le16_to_cpu(*pressure) & 0xfff); | |
494 | input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff); | 497 | pressure++; |
495 | } | 498 | } |
496 | 499 | ||
497 | input_sync(dev->input_dev); | 500 | input_sync(cdev->input_dev); |
498 | } | 501 | } |
499 | 502 | ||
500 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | 503 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) |
501 | { | 504 | { |
502 | struct snd_usb_caiaqdev *dev = urb->context; | 505 | struct snd_usb_caiaqdev *cdev = urb->context; |
503 | unsigned char *buf = urb->transfer_buffer; | 506 | unsigned char *buf = urb->transfer_buffer; |
507 | struct device *dev = &urb->dev->dev; | ||
504 | int ret; | 508 | int ret; |
505 | 509 | ||
506 | if (urb->status || !dev || urb != dev->ep4_in_urb) | 510 | if (urb->status || !cdev || urb != cdev->ep4_in_urb) |
507 | return; | 511 | return; |
508 | 512 | ||
509 | switch (dev->chip.usb_id) { | 513 | switch (cdev->chip.usb_id) { |
510 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 514 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
511 | if (urb->actual_length < 24) | 515 | if (urb->actual_length < 24) |
512 | goto requeue; | 516 | goto requeue; |
513 | 517 | ||
514 | if (buf[0] & 0x3) | 518 | if (buf[0] & 0x3) |
515 | snd_caiaq_input_read_io(dev, buf + 1, 7); | 519 | snd_caiaq_input_read_io(cdev, buf + 1, 7); |
516 | 520 | ||
517 | if (buf[0] & 0x4) | 521 | if (buf[0] & 0x4) |
518 | snd_caiaq_input_read_analog(dev, buf + 8, 16); | 522 | snd_caiaq_input_read_analog(cdev, buf + 8, 16); |
519 | 523 | ||
520 | break; | 524 | break; |
521 | 525 | ||
522 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
523 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); | 527 | snd_usb_caiaq_tks4_dispatch(cdev, buf, urb->actual_length); |
524 | break; | 528 | break; |
525 | 529 | ||
526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | 530 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): |
527 | if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) | 531 | if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) |
528 | goto requeue; | 532 | goto requeue; |
529 | 533 | ||
530 | snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length); | 534 | snd_usb_caiaq_maschine_dispatch(cdev, buf, urb->actual_length); |
531 | break; | 535 | break; |
532 | } | 536 | } |
533 | 537 | ||
534 | requeue: | 538 | requeue: |
535 | dev->ep4_in_urb->actual_length = 0; | 539 | cdev->ep4_in_urb->actual_length = 0; |
536 | ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC); | 540 | ret = usb_submit_urb(cdev->ep4_in_urb, GFP_ATOMIC); |
537 | if (ret < 0) | 541 | if (ret < 0) |
538 | log("unable to submit urb. OOM!?\n"); | 542 | dev_err(dev, "unable to submit urb. OOM!?\n"); |
539 | } | 543 | } |
540 | 544 | ||
541 | static int snd_usb_caiaq_input_open(struct input_dev *idev) | 545 | static int snd_usb_caiaq_input_open(struct input_dev *idev) |
542 | { | 546 | { |
543 | struct snd_usb_caiaqdev *dev = input_get_drvdata(idev); | 547 | struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev); |
544 | 548 | ||
545 | if (!dev) | 549 | if (!cdev) |
546 | return -EINVAL; | 550 | return -EINVAL; |
547 | 551 | ||
548 | switch (dev->chip.usb_id) { | 552 | switch (cdev->chip.usb_id) { |
549 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 553 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
550 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 554 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | 555 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): |
552 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) | 556 | if (usb_submit_urb(cdev->ep4_in_urb, GFP_KERNEL) != 0) |
553 | return -EIO; | 557 | return -EIO; |
554 | break; | 558 | break; |
555 | } | 559 | } |
@@ -559,43 +563,43 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev) | |||
559 | 563 | ||
560 | static void snd_usb_caiaq_input_close(struct input_dev *idev) | 564 | static void snd_usb_caiaq_input_close(struct input_dev *idev) |
561 | { | 565 | { |
562 | struct snd_usb_caiaqdev *dev = input_get_drvdata(idev); | 566 | struct snd_usb_caiaqdev *cdev = input_get_drvdata(idev); |
563 | 567 | ||
564 | if (!dev) | 568 | if (!cdev) |
565 | return; | 569 | return; |
566 | 570 | ||
567 | switch (dev->chip.usb_id) { | 571 | switch (cdev->chip.usb_id) { |
568 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 572 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
569 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 573 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
570 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | 574 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): |
571 | usb_kill_urb(dev->ep4_in_urb); | 575 | usb_kill_urb(cdev->ep4_in_urb); |
572 | break; | 576 | break; |
573 | } | 577 | } |
574 | } | 578 | } |
575 | 579 | ||
576 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, | 580 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, |
577 | char *buf, | 581 | char *buf, |
578 | unsigned int len) | 582 | unsigned int len) |
579 | { | 583 | { |
580 | if (!dev->input_dev || len < 1) | 584 | if (!cdev->input_dev || len < 1) |
581 | return; | 585 | return; |
582 | 586 | ||
583 | switch (buf[0]) { | 587 | switch (buf[0]) { |
584 | case EP1_CMD_READ_ANALOG: | 588 | case EP1_CMD_READ_ANALOG: |
585 | snd_caiaq_input_read_analog(dev, buf + 1, len - 1); | 589 | snd_caiaq_input_read_analog(cdev, buf + 1, len - 1); |
586 | break; | 590 | break; |
587 | case EP1_CMD_READ_ERP: | 591 | case EP1_CMD_READ_ERP: |
588 | snd_caiaq_input_read_erp(dev, buf + 1, len - 1); | 592 | snd_caiaq_input_read_erp(cdev, buf + 1, len - 1); |
589 | break; | 593 | break; |
590 | case EP1_CMD_READ_IO: | 594 | case EP1_CMD_READ_IO: |
591 | snd_caiaq_input_read_io(dev, buf + 1, len - 1); | 595 | snd_caiaq_input_read_io(cdev, buf + 1, len - 1); |
592 | break; | 596 | break; |
593 | } | 597 | } |
594 | } | 598 | } |
595 | 599 | ||
596 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | 600 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev) |
597 | { | 601 | { |
598 | struct usb_device *usb_dev = dev->chip.dev; | 602 | struct usb_device *usb_dev = cdev->chip.dev; |
599 | struct input_dev *input; | 603 | struct input_dev *input; |
600 | int i, ret = 0; | 604 | int i, ret = 0; |
601 | 605 | ||
@@ -603,49 +607,49 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
603 | if (!input) | 607 | if (!input) |
604 | return -ENOMEM; | 608 | return -ENOMEM; |
605 | 609 | ||
606 | usb_make_path(usb_dev, dev->phys, sizeof(dev->phys)); | 610 | usb_make_path(usb_dev, cdev->phys, sizeof(cdev->phys)); |
607 | strlcat(dev->phys, "/input0", sizeof(dev->phys)); | 611 | strlcat(cdev->phys, "/input0", sizeof(cdev->phys)); |
608 | 612 | ||
609 | input->name = dev->product_name; | 613 | input->name = cdev->product_name; |
610 | input->phys = dev->phys; | 614 | input->phys = cdev->phys; |
611 | usb_to_input_id(usb_dev, &input->id); | 615 | usb_to_input_id(usb_dev, &input->id); |
612 | input->dev.parent = &usb_dev->dev; | 616 | input->dev.parent = &usb_dev->dev; |
613 | 617 | ||
614 | input_set_drvdata(input, dev); | 618 | input_set_drvdata(input, cdev); |
615 | 619 | ||
616 | switch (dev->chip.usb_id) { | 620 | switch (cdev->chip.usb_id) { |
617 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): | 621 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): |
618 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 622 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
619 | input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 623 | input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | |
620 | BIT_MASK(ABS_Z); | 624 | BIT_MASK(ABS_Z); |
621 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk2)); | 625 | BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk2)); |
622 | memcpy(dev->keycode, keycode_rk2, sizeof(keycode_rk2)); | 626 | memcpy(cdev->keycode, keycode_rk2, sizeof(keycode_rk2)); |
623 | input->keycodemax = ARRAY_SIZE(keycode_rk2); | 627 | input->keycodemax = ARRAY_SIZE(keycode_rk2); |
624 | input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); | 628 | input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); |
625 | input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); | 629 | input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); |
626 | input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); | 630 | input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); |
627 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); | 631 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0); |
628 | break; | 632 | break; |
629 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): | 633 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): |
630 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 634 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
631 | input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 635 | input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | |
632 | BIT_MASK(ABS_Z); | 636 | BIT_MASK(ABS_Z); |
633 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3)); | 637 | BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_rk3)); |
634 | memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3)); | 638 | memcpy(cdev->keycode, keycode_rk3, sizeof(keycode_rk3)); |
635 | input->keycodemax = ARRAY_SIZE(keycode_rk3); | 639 | input->keycodemax = ARRAY_SIZE(keycode_rk3); |
636 | input_set_abs_params(input, ABS_X, 0, 1024, 0, 10); | 640 | input_set_abs_params(input, ABS_X, 0, 1024, 0, 10); |
637 | input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10); | 641 | input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10); |
638 | input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10); | 642 | input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10); |
639 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); | 643 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 0); |
640 | break; | 644 | break; |
641 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): | 645 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): |
642 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 646 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
643 | input->absbit[0] = BIT_MASK(ABS_X); | 647 | input->absbit[0] = BIT_MASK(ABS_X); |
644 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1)); | 648 | BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_ak1)); |
645 | memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1)); | 649 | memcpy(cdev->keycode, keycode_ak1, sizeof(keycode_ak1)); |
646 | input->keycodemax = ARRAY_SIZE(keycode_ak1); | 650 | input->keycodemax = ARRAY_SIZE(keycode_ak1); |
647 | input_set_abs_params(input, ABS_X, 0, 999, 0, 10); | 651 | input_set_abs_params(input, ABS_X, 0, 999, 0, 10); |
648 | snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); | 652 | snd_usb_caiaq_set_auto_msg(cdev, 1, 0, 5); |
649 | break; | 653 | break; |
650 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): | 654 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): |
651 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): | 655 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): |
@@ -657,8 +661,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
657 | BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 661 | BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | |
658 | BIT_MASK(ABS_Z); | 662 | BIT_MASK(ABS_Z); |
659 | input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 663 | input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
660 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore)); | 664 | BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_kore)); |
661 | memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore)); | 665 | memcpy(cdev->keycode, keycode_kore, sizeof(keycode_kore)); |
662 | input->keycodemax = ARRAY_SIZE(keycode_kore); | 666 | input->keycodemax = ARRAY_SIZE(keycode_kore); |
663 | input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); | 667 | input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); |
664 | input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); | 668 | input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); |
@@ -672,7 +676,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
672 | input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); | 676 | input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); |
673 | input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); | 677 | input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); |
674 | input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); | 678 | input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); |
675 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 679 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); |
676 | break; | 680 | break; |
677 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 681 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
678 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 682 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
@@ -683,9 +687,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
683 | BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | | 687 | BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | |
684 | BIT_MASK(ABS_Z); | 688 | BIT_MASK(ABS_Z); |
685 | input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 689 | input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
686 | BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS); | 690 | BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLX1_INPUTS); |
687 | for (i = 0; i < KONTROLX1_INPUTS; i++) | 691 | for (i = 0; i < KONTROLX1_INPUTS; i++) |
688 | dev->keycode[i] = BTN_MISC + i; | 692 | cdev->keycode[i] = BTN_MISC + i; |
689 | input->keycodemax = KONTROLX1_INPUTS; | 693 | input->keycodemax = KONTROLX1_INPUTS; |
690 | 694 | ||
691 | /* analog potentiometers */ | 695 | /* analog potentiometers */ |
@@ -704,26 +708,26 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
704 | input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1); | 708 | input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1); |
705 | input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1); | 709 | input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1); |
706 | 710 | ||
707 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 711 | cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
708 | if (!dev->ep4_in_urb) { | 712 | if (!cdev->ep4_in_urb) { |
709 | ret = -ENOMEM; | 713 | ret = -ENOMEM; |
710 | goto exit_free_idev; | 714 | goto exit_free_idev; |
711 | } | 715 | } |
712 | 716 | ||
713 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | 717 | usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, |
714 | usb_rcvbulkpipe(usb_dev, 0x4), | 718 | usb_rcvbulkpipe(usb_dev, 0x4), |
715 | dev->ep4_in_buf, EP4_BUFSIZE, | 719 | cdev->ep4_in_buf, EP4_BUFSIZE, |
716 | snd_usb_caiaq_ep4_reply_dispatch, dev); | 720 | snd_usb_caiaq_ep4_reply_dispatch, cdev); |
717 | 721 | ||
718 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 722 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); |
719 | 723 | ||
720 | break; | 724 | break; |
721 | 725 | ||
722 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 726 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
723 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 727 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
724 | BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS); | 728 | BUILD_BUG_ON(sizeof(cdev->keycode) < KONTROLS4_BUTTONS); |
725 | for (i = 0; i < KONTROLS4_BUTTONS; i++) | 729 | for (i = 0; i < KONTROLS4_BUTTONS; i++) |
726 | dev->keycode[i] = KONTROLS4_BUTTON(i); | 730 | cdev->keycode[i] = KONTROLS4_BUTTON(i); |
727 | input->keycodemax = KONTROLS4_BUTTONS; | 731 | input->keycodemax = KONTROLS4_BUTTONS; |
728 | 732 | ||
729 | for (i = 0; i < KONTROLS4_AXIS; i++) { | 733 | for (i = 0; i < KONTROLS4_AXIS; i++) { |
@@ -743,18 +747,18 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
743 | for (i = 0; i < 9; i++) | 747 | for (i = 0; i < 9; i++) |
744 | input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1); | 748 | input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1); |
745 | 749 | ||
746 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 750 | cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
747 | if (!dev->ep4_in_urb) { | 751 | if (!cdev->ep4_in_urb) { |
748 | ret = -ENOMEM; | 752 | ret = -ENOMEM; |
749 | goto exit_free_idev; | 753 | goto exit_free_idev; |
750 | } | 754 | } |
751 | 755 | ||
752 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | 756 | usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, |
753 | usb_rcvbulkpipe(usb_dev, 0x4), | 757 | usb_rcvbulkpipe(usb_dev, 0x4), |
754 | dev->ep4_in_buf, EP4_BUFSIZE, | 758 | cdev->ep4_in_buf, EP4_BUFSIZE, |
755 | snd_usb_caiaq_ep4_reply_dispatch, dev); | 759 | snd_usb_caiaq_ep4_reply_dispatch, cdev); |
756 | 760 | ||
757 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 761 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); |
758 | 762 | ||
759 | break; | 763 | break; |
760 | 764 | ||
@@ -767,8 +771,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
767 | BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | | 771 | BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | |
768 | BIT_MASK(ABS_RZ); | 772 | BIT_MASK(ABS_RZ); |
769 | 773 | ||
770 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine)); | 774 | BUILD_BUG_ON(sizeof(cdev->keycode) < sizeof(keycode_maschine)); |
771 | memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine)); | 775 | memcpy(cdev->keycode, keycode_maschine, sizeof(keycode_maschine)); |
772 | input->keycodemax = ARRAY_SIZE(keycode_maschine); | 776 | input->keycodemax = ARRAY_SIZE(keycode_maschine); |
773 | 777 | ||
774 | for (i = 0; i < MASCHINE_PADS; i++) { | 778 | for (i = 0; i < MASCHINE_PADS; i++) { |
@@ -788,18 +792,18 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
788 | input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); | 792 | input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); |
789 | input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); | 793 | input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); |
790 | 794 | ||
791 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | 795 | cdev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); |
792 | if (!dev->ep4_in_urb) { | 796 | if (!cdev->ep4_in_urb) { |
793 | ret = -ENOMEM; | 797 | ret = -ENOMEM; |
794 | goto exit_free_idev; | 798 | goto exit_free_idev; |
795 | } | 799 | } |
796 | 800 | ||
797 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | 801 | usb_fill_bulk_urb(cdev->ep4_in_urb, usb_dev, |
798 | usb_rcvbulkpipe(usb_dev, 0x4), | 802 | usb_rcvbulkpipe(usb_dev, 0x4), |
799 | dev->ep4_in_buf, EP4_BUFSIZE, | 803 | cdev->ep4_in_buf, EP4_BUFSIZE, |
800 | snd_usb_caiaq_ep4_reply_dispatch, dev); | 804 | snd_usb_caiaq_ep4_reply_dispatch, cdev); |
801 | 805 | ||
802 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | 806 | snd_usb_caiaq_set_auto_msg(cdev, 1, 10, 5); |
803 | break; | 807 | break; |
804 | 808 | ||
805 | default: | 809 | default: |
@@ -809,12 +813,12 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
809 | 813 | ||
810 | input->open = snd_usb_caiaq_input_open; | 814 | input->open = snd_usb_caiaq_input_open; |
811 | input->close = snd_usb_caiaq_input_close; | 815 | input->close = snd_usb_caiaq_input_close; |
812 | input->keycode = dev->keycode; | 816 | input->keycode = cdev->keycode; |
813 | input->keycodesize = sizeof(unsigned short); | 817 | input->keycodesize = sizeof(unsigned short); |
814 | for (i = 0; i < input->keycodemax; i++) | 818 | for (i = 0; i < input->keycodemax; i++) |
815 | __set_bit(dev->keycode[i], input->keybit); | 819 | __set_bit(cdev->keycode[i], input->keybit); |
816 | 820 | ||
817 | dev->input_dev = input; | 821 | cdev->input_dev = input; |
818 | 822 | ||
819 | ret = input_register_device(input); | 823 | ret = input_register_device(input); |
820 | if (ret < 0) | 824 | if (ret < 0) |
@@ -824,19 +828,19 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
824 | 828 | ||
825 | exit_free_idev: | 829 | exit_free_idev: |
826 | input_free_device(input); | 830 | input_free_device(input); |
827 | dev->input_dev = NULL; | 831 | cdev->input_dev = NULL; |
828 | return ret; | 832 | return ret; |
829 | } | 833 | } |
830 | 834 | ||
831 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | 835 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev) |
832 | { | 836 | { |
833 | if (!dev || !dev->input_dev) | 837 | if (!cdev || !cdev->input_dev) |
834 | return; | 838 | return; |
835 | 839 | ||
836 | usb_kill_urb(dev->ep4_in_urb); | 840 | usb_kill_urb(cdev->ep4_in_urb); |
837 | usb_free_urb(dev->ep4_in_urb); | 841 | usb_free_urb(cdev->ep4_in_urb); |
838 | dev->ep4_in_urb = NULL; | 842 | cdev->ep4_in_urb = NULL; |
839 | 843 | ||
840 | input_unregister_device(dev->input_dev); | 844 | input_unregister_device(cdev->input_dev); |
841 | dev->input_dev = NULL; | 845 | cdev->input_dev = NULL; |
842 | } | 846 | } |
diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h index ced535577864..6014e2713a60 100644 --- a/sound/usb/caiaq/input.h +++ b/sound/usb/caiaq/input.h | |||
@@ -1,8 +1,8 @@ | |||
1 | #ifndef CAIAQ_INPUT_H | 1 | #ifndef CAIAQ_INPUT_H |
2 | #define CAIAQ_INPUT_H | 2 | #define CAIAQ_INPUT_H |
3 | 3 | ||
4 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len); | 4 | void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *cdev, char *buf, unsigned int len); |
5 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev); | 5 | int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev); |
6 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev); | 6 | void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *cdev); |
7 | 7 | ||
8 | #endif | 8 | #endif |
diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c index a1a47088fd0c..2d7588461b33 100644 --- a/sound/usb/caiaq/midi.c +++ b/sound/usb/caiaq/midi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/device.h> | ||
19 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
20 | #include <linux/gfp.h> | 21 | #include <linux/gfp.h> |
21 | #include <sound/rawmidi.h> | 22 | #include <sound/rawmidi.h> |
@@ -37,12 +38,12 @@ static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substrea | |||
37 | 38 | ||
38 | static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 39 | static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) |
39 | { | 40 | { |
40 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | 41 | struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data; |
41 | 42 | ||
42 | if (!dev) | 43 | if (!cdev) |
43 | return; | 44 | return; |
44 | 45 | ||
45 | dev->midi_receive_substream = up ? substream : NULL; | 46 | cdev->midi_receive_substream = up ? substream : NULL; |
46 | } | 47 | } |
47 | 48 | ||
48 | 49 | ||
@@ -53,49 +54,50 @@ static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substrea | |||
53 | 54 | ||
54 | static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) | 55 | static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) |
55 | { | 56 | { |
56 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | 57 | struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data; |
57 | if (dev->midi_out_active) { | 58 | if (cdev->midi_out_active) { |
58 | usb_kill_urb(&dev->midi_out_urb); | 59 | usb_kill_urb(&cdev->midi_out_urb); |
59 | dev->midi_out_active = 0; | 60 | cdev->midi_out_active = 0; |
60 | } | 61 | } |
61 | return 0; | 62 | return 0; |
62 | } | 63 | } |
63 | 64 | ||
64 | static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, | 65 | static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *cdev, |
65 | struct snd_rawmidi_substream *substream) | 66 | struct snd_rawmidi_substream *substream) |
66 | { | 67 | { |
67 | int len, ret; | 68 | int len, ret; |
69 | struct device *dev = caiaqdev_to_dev(cdev); | ||
68 | 70 | ||
69 | dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; | 71 | cdev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; |
70 | dev->midi_out_buf[1] = 0; /* port */ | 72 | cdev->midi_out_buf[1] = 0; /* port */ |
71 | len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3, | 73 | len = snd_rawmidi_transmit(substream, cdev->midi_out_buf + 3, |
72 | EP1_BUFSIZE - 3); | 74 | EP1_BUFSIZE - 3); |
73 | 75 | ||
74 | if (len <= 0) | 76 | if (len <= 0) |
75 | return; | 77 | return; |
76 | 78 | ||
77 | dev->midi_out_buf[2] = len; | 79 | cdev->midi_out_buf[2] = len; |
78 | dev->midi_out_urb.transfer_buffer_length = len+3; | 80 | cdev->midi_out_urb.transfer_buffer_length = len+3; |
79 | 81 | ||
80 | ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); | 82 | ret = usb_submit_urb(&cdev->midi_out_urb, GFP_ATOMIC); |
81 | if (ret < 0) | 83 | if (ret < 0) |
82 | log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed," | 84 | dev_err(dev, |
83 | "ret=%d, len=%d\n", | 85 | "snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed," |
84 | substream, ret, len); | 86 | "ret=%d, len=%d\n", substream, ret, len); |
85 | else | 87 | else |
86 | dev->midi_out_active = 1; | 88 | cdev->midi_out_active = 1; |
87 | } | 89 | } |
88 | 90 | ||
89 | static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) | 91 | static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) |
90 | { | 92 | { |
91 | struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; | 93 | struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data; |
92 | 94 | ||
93 | if (up) { | 95 | if (up) { |
94 | dev->midi_out_substream = substream; | 96 | cdev->midi_out_substream = substream; |
95 | if (!dev->midi_out_active) | 97 | if (!cdev->midi_out_active) |
96 | snd_usb_caiaq_midi_send(dev, substream); | 98 | snd_usb_caiaq_midi_send(cdev, substream); |
97 | } else { | 99 | } else { |
98 | dev->midi_out_substream = NULL; | 100 | cdev->midi_out_substream = NULL; |
99 | } | 101 | } |
100 | } | 102 | } |
101 | 103 | ||
@@ -114,13 +116,13 @@ static struct snd_rawmidi_ops snd_usb_caiaq_midi_input = | |||
114 | .trigger = snd_usb_caiaq_midi_input_trigger, | 116 | .trigger = snd_usb_caiaq_midi_input_trigger, |
115 | }; | 117 | }; |
116 | 118 | ||
117 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, | 119 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *cdev, |
118 | int port, const char *buf, int len) | 120 | int port, const char *buf, int len) |
119 | { | 121 | { |
120 | if (!dev->midi_receive_substream) | 122 | if (!cdev->midi_receive_substream) |
121 | return; | 123 | return; |
122 | 124 | ||
123 | snd_rawmidi_receive(dev->midi_receive_substream, buf, len); | 125 | snd_rawmidi_receive(cdev->midi_receive_substream, buf, len); |
124 | } | 126 | } |
125 | 127 | ||
126 | int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) | 128 | int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) |
@@ -160,15 +162,14 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) | |||
160 | 162 | ||
161 | void snd_usb_caiaq_midi_output_done(struct urb* urb) | 163 | void snd_usb_caiaq_midi_output_done(struct urb* urb) |
162 | { | 164 | { |
163 | struct snd_usb_caiaqdev *dev = urb->context; | 165 | struct snd_usb_caiaqdev *cdev = urb->context; |
164 | 166 | ||
165 | dev->midi_out_active = 0; | 167 | cdev->midi_out_active = 0; |
166 | if (urb->status != 0) | 168 | if (urb->status != 0) |
167 | return; | 169 | return; |
168 | 170 | ||
169 | if (!dev->midi_out_substream) | 171 | if (!cdev->midi_out_substream) |
170 | return; | 172 | return; |
171 | 173 | ||
172 | snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); | 174 | snd_usb_caiaq_midi_send(cdev, cdev->midi_out_substream); |
173 | } | 175 | } |
174 | |||
diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h index 380f984babc9..60bf3442b283 100644 --- a/sound/usb/caiaq/midi.h +++ b/sound/usb/caiaq/midi.h | |||
@@ -1,8 +1,9 @@ | |||
1 | #ifndef CAIAQ_MIDI_H | 1 | #ifndef CAIAQ_MIDI_H |
2 | #define CAIAQ_MIDI_H | 2 | #define CAIAQ_MIDI_H |
3 | 3 | ||
4 | int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); | 4 | int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *cdev); |
5 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); | 5 | void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *cdev, |
6 | int port, const char *buf, int len); | ||
6 | void snd_usb_caiaq_midi_output_done(struct urb *urb); | 7 | void snd_usb_caiaq_midi_output_done(struct urb *urb); |
7 | 8 | ||
8 | #endif /* CAIAQ_MIDI_H */ | 9 | #endif /* CAIAQ_MIDI_H */ |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 2da8ad75fd96..1a033177b83f 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -82,6 +82,7 @@ static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; | |||
82 | static int nrpacks = 8; /* max. number of packets per urb */ | 82 | static int nrpacks = 8; /* max. number of packets per urb */ |
83 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ | 83 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ |
84 | static bool ignore_ctl_error; | 84 | static bool ignore_ctl_error; |
85 | static bool autoclock = true; | ||
85 | 86 | ||
86 | module_param_array(index, int, NULL, 0444); | 87 | module_param_array(index, int, NULL, 0444); |
87 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 88 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
@@ -100,6 +101,8 @@ MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); | |||
100 | module_param(ignore_ctl_error, bool, 0444); | 101 | module_param(ignore_ctl_error, bool, 0444); |
101 | MODULE_PARM_DESC(ignore_ctl_error, | 102 | MODULE_PARM_DESC(ignore_ctl_error, |
102 | "Ignore errors from USB controller for mixer interfaces."); | 103 | "Ignore errors from USB controller for mixer interfaces."); |
104 | module_param(autoclock, bool, 0444); | ||
105 | MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); | ||
103 | 106 | ||
104 | /* | 107 | /* |
105 | * we keep the snd_usb_audio_t instances by ourselves for merging | 108 | * we keep the snd_usb_audio_t instances by ourselves for merging |
@@ -354,6 +357,7 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, | |||
354 | chip->card = card; | 357 | chip->card = card; |
355 | chip->setup = device_setup[idx]; | 358 | chip->setup = device_setup[idx]; |
356 | chip->nrpacks = nrpacks; | 359 | chip->nrpacks = nrpacks; |
360 | chip->autoclock = autoclock; | ||
357 | chip->probing = 1; | 361 | chip->probing = 1; |
358 | 362 | ||
359 | chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), | 363 | chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), |
@@ -627,7 +631,9 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
627 | int err = -ENODEV; | 631 | int err = -ENODEV; |
628 | 632 | ||
629 | down_read(&chip->shutdown_rwsem); | 633 | down_read(&chip->shutdown_rwsem); |
630 | if (!chip->shutdown && !chip->probing) | 634 | if (chip->probing) |
635 | err = 0; | ||
636 | else if (!chip->shutdown) | ||
631 | err = usb_autopm_get_interface(chip->pm_intf); | 637 | err = usb_autopm_get_interface(chip->pm_intf); |
632 | up_read(&chip->shutdown_rwsem); | 638 | up_read(&chip->shutdown_rwsem); |
633 | 639 | ||
@@ -645,7 +651,6 @@ void snd_usb_autosuspend(struct snd_usb_audio *chip) | |||
645 | static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | 651 | static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) |
646 | { | 652 | { |
647 | struct snd_usb_audio *chip = usb_get_intfdata(intf); | 653 | struct snd_usb_audio *chip = usb_get_intfdata(intf); |
648 | struct list_head *p; | ||
649 | struct snd_usb_stream *as; | 654 | struct snd_usb_stream *as; |
650 | struct usb_mixer_interface *mixer; | 655 | struct usb_mixer_interface *mixer; |
651 | 656 | ||
@@ -655,8 +660,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | |||
655 | if (!PMSG_IS_AUTO(message)) { | 660 | if (!PMSG_IS_AUTO(message)) { |
656 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); | 661 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); |
657 | if (!chip->num_suspended_intf++) { | 662 | if (!chip->num_suspended_intf++) { |
658 | list_for_each(p, &chip->pcm_list) { | 663 | list_for_each_entry(as, &chip->pcm_list, list) { |
659 | as = list_entry(p, struct snd_usb_stream, list); | ||
660 | snd_pcm_suspend_all(as->pcm); | 664 | snd_pcm_suspend_all(as->pcm); |
661 | as->substream[0].need_setup_ep = | 665 | as->substream[0].need_setup_ep = |
662 | as->substream[1].need_setup_ep = true; | 666 | as->substream[1].need_setup_ep = true; |
@@ -716,8 +720,7 @@ static struct usb_device_id usb_audio_ids [] = { | |||
716 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL }, | 720 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL }, |
717 | { } /* Terminating entry */ | 721 | { } /* Terminating entry */ |
718 | }; | 722 | }; |
719 | 723 | MODULE_DEVICE_TABLE(usb, usb_audio_ids); | |
720 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | ||
721 | 724 | ||
722 | /* | 725 | /* |
723 | * entry point for linux usb interface | 726 | * entry point for linux usb interface |
diff --git a/sound/usb/card.h b/sound/usb/card.h index 8a751b4887ea..bf2889a2cae5 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -28,6 +28,8 @@ struct audioformat { | |||
28 | unsigned int *rate_table; /* rate table */ | 28 | unsigned int *rate_table; /* rate table */ |
29 | unsigned char clock; /* associated clock */ | 29 | unsigned char clock; /* associated clock */ |
30 | struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ | 30 | struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ |
31 | bool dsd_dop; /* add DOP headers in case of DSD samples */ | ||
32 | bool dsd_bitrev; /* reverse the bits of each DSD sample */ | ||
31 | }; | 33 | }; |
32 | 34 | ||
33 | struct snd_usb_substream; | 35 | struct snd_usb_substream; |
@@ -116,6 +118,7 @@ struct snd_usb_substream { | |||
116 | unsigned int altset_idx; /* USB data format: index of alternate setting */ | 118 | unsigned int altset_idx; /* USB data format: index of alternate setting */ |
117 | unsigned int txfr_quirk:1; /* allow sub-frame alignment */ | 119 | unsigned int txfr_quirk:1; /* allow sub-frame alignment */ |
118 | unsigned int fmt_type; /* USB audio format type (1-3) */ | 120 | unsigned int fmt_type; /* USB audio format type (1-3) */ |
121 | unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */ | ||
119 | 122 | ||
120 | unsigned int running: 1; /* running status */ | 123 | unsigned int running: 1; /* running status */ |
121 | 124 | ||
@@ -138,6 +141,12 @@ struct snd_usb_substream { | |||
138 | 141 | ||
139 | int last_frame_number; /* stored frame number */ | 142 | int last_frame_number; /* stored frame number */ |
140 | int last_delay; /* stored delay */ | 143 | int last_delay; /* stored delay */ |
144 | |||
145 | struct { | ||
146 | int marker; | ||
147 | int channel; | ||
148 | int byte_idx; | ||
149 | } dsd_dop; | ||
141 | }; | 150 | }; |
142 | 151 | ||
143 | struct snd_usb_stream { | 152 | struct snd_usb_stream { |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 9e2703a25156..3a2ce390e278 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "card.h" | 32 | #include "card.h" |
33 | #include "helper.h" | 33 | #include "helper.h" |
34 | #include "clock.h" | 34 | #include "clock.h" |
35 | #include "quirks.h" | ||
35 | 36 | ||
36 | static struct uac_clock_source_descriptor * | 37 | static struct uac_clock_source_descriptor * |
37 | snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface, | 38 | snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface, |
@@ -99,6 +100,41 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i | |||
99 | return buf; | 100 | return buf; |
100 | } | 101 | } |
101 | 102 | ||
103 | static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_id, | ||
104 | unsigned char pin) | ||
105 | { | ||
106 | int ret; | ||
107 | |||
108 | ret = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), | ||
109 | UAC2_CS_CUR, | ||
110 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | ||
111 | UAC2_CX_CLOCK_SELECTOR << 8, | ||
112 | snd_usb_ctrl_intf(chip) | (selector_id << 8), | ||
113 | &pin, sizeof(pin)); | ||
114 | if (ret < 0) | ||
115 | return ret; | ||
116 | |||
117 | if (ret != sizeof(pin)) { | ||
118 | snd_printk(KERN_ERR | ||
119 | "usb-audio:%d: setting selector (id %d) unexpected length %d\n", | ||
120 | chip->dev->devnum, selector_id, ret); | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | ret = uac_clock_selector_get_val(chip, selector_id); | ||
125 | if (ret < 0) | ||
126 | return ret; | ||
127 | |||
128 | if (ret != pin) { | ||
129 | snd_printk(KERN_ERR | ||
130 | "usb-audio:%d: setting selector (id %d) to %x failed (current: %d)\n", | ||
131 | chip->dev->devnum, selector_id, pin, ret); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | return ret; | ||
136 | } | ||
137 | |||
102 | static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | 138 | static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) |
103 | { | 139 | { |
104 | int err; | 140 | int err; |
@@ -131,7 +167,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
131 | } | 167 | } |
132 | 168 | ||
133 | static int __uac_clock_find_source(struct snd_usb_audio *chip, | 169 | static int __uac_clock_find_source(struct snd_usb_audio *chip, |
134 | int entity_id, unsigned long *visited) | 170 | int entity_id, unsigned long *visited, |
171 | bool validate) | ||
135 | { | 172 | { |
136 | struct uac_clock_source_descriptor *source; | 173 | struct uac_clock_source_descriptor *source; |
137 | struct uac_clock_selector_descriptor *selector; | 174 | struct uac_clock_selector_descriptor *selector; |
@@ -148,12 +185,19 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
148 | 185 | ||
149 | /* first, see if the ID we're looking for is a clock source already */ | 186 | /* first, see if the ID we're looking for is a clock source already */ |
150 | source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); | 187 | source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); |
151 | if (source) | 188 | if (source) { |
152 | return source->bClockID; | 189 | entity_id = source->bClockID; |
190 | if (validate && !uac_clock_source_is_valid(chip, entity_id)) { | ||
191 | snd_printk(KERN_ERR "usb-audio:%d: clock source %d is not valid, cannot use\n", | ||
192 | chip->dev->devnum, entity_id); | ||
193 | return -ENXIO; | ||
194 | } | ||
195 | return entity_id; | ||
196 | } | ||
153 | 197 | ||
154 | selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id); | 198 | selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id); |
155 | if (selector) { | 199 | if (selector) { |
156 | int ret; | 200 | int ret, i, cur; |
157 | 201 | ||
158 | /* the entity ID we are looking for is a selector. | 202 | /* the entity ID we are looking for is a selector. |
159 | * find out what it currently selects */ | 203 | * find out what it currently selects */ |
@@ -164,22 +208,49 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
164 | /* Selector values are one-based */ | 208 | /* Selector values are one-based */ |
165 | 209 | ||
166 | if (ret > selector->bNrInPins || ret < 1) { | 210 | if (ret > selector->bNrInPins || ret < 1) { |
167 | printk(KERN_ERR | 211 | snd_printk(KERN_ERR |
168 | "%s(): selector reported illegal value, id %d, ret %d\n", | 212 | "%s(): selector reported illegal value, id %d, ret %d\n", |
169 | __func__, selector->bClockID, ret); | 213 | __func__, selector->bClockID, ret); |
170 | 214 | ||
171 | return -EINVAL; | 215 | return -EINVAL; |
172 | } | 216 | } |
173 | 217 | ||
174 | return __uac_clock_find_source(chip, selector->baCSourceID[ret-1], | 218 | cur = ret; |
175 | visited); | 219 | ret = __uac_clock_find_source(chip, selector->baCSourceID[ret - 1], |
220 | visited, validate); | ||
221 | if (!validate || ret > 0 || !chip->autoclock) | ||
222 | return ret; | ||
223 | |||
224 | /* The current clock source is invalid, try others. */ | ||
225 | for (i = 1; i <= selector->bNrInPins; i++) { | ||
226 | int err; | ||
227 | |||
228 | if (i == cur) | ||
229 | continue; | ||
230 | |||
231 | ret = __uac_clock_find_source(chip, selector->baCSourceID[i - 1], | ||
232 | visited, true); | ||
233 | if (ret < 0) | ||
234 | continue; | ||
235 | |||
236 | err = uac_clock_selector_set_val(chip, entity_id, i); | ||
237 | if (err < 0) | ||
238 | continue; | ||
239 | |||
240 | snd_printk(KERN_INFO | ||
241 | "usb-audio:%d: found and selected valid clock source %d\n", | ||
242 | chip->dev->devnum, ret); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | return -ENXIO; | ||
176 | } | 247 | } |
177 | 248 | ||
178 | /* FIXME: multipliers only act as pass-thru element for now */ | 249 | /* FIXME: multipliers only act as pass-thru element for now */ |
179 | multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id); | 250 | multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id); |
180 | if (multiplier) | 251 | if (multiplier) |
181 | return __uac_clock_find_source(chip, multiplier->bCSourceID, | 252 | return __uac_clock_find_source(chip, multiplier->bCSourceID, |
182 | visited); | 253 | visited, validate); |
183 | 254 | ||
184 | return -EINVAL; | 255 | return -EINVAL; |
185 | } | 256 | } |
@@ -195,11 +266,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
195 | * | 266 | * |
196 | * Returns the clock source UnitID (>=0) on success, or an error. | 267 | * Returns the clock source UnitID (>=0) on success, or an error. |
197 | */ | 268 | */ |
198 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id) | 269 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id, |
270 | bool validate) | ||
199 | { | 271 | { |
200 | DECLARE_BITMAP(visited, 256); | 272 | DECLARE_BITMAP(visited, 256); |
201 | memset(visited, 0, sizeof(visited)); | 273 | memset(visited, 0, sizeof(visited)); |
202 | return __uac_clock_find_source(chip, entity_id, visited); | 274 | return __uac_clock_find_source(chip, entity_id, visited, validate); |
203 | } | 275 | } |
204 | 276 | ||
205 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | 277 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, |
@@ -247,66 +319,73 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
247 | return 0; | 319 | return 0; |
248 | } | 320 | } |
249 | 321 | ||
322 | static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface, | ||
323 | int altsetting, int clock) | ||
324 | { | ||
325 | struct usb_device *dev = chip->dev; | ||
326 | __le32 data; | ||
327 | int err; | ||
328 | |||
329 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
330 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
331 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
332 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
333 | &data, sizeof(data)); | ||
334 | if (err < 0) { | ||
335 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2): err %d\n", | ||
336 | dev->devnum, iface, altsetting, err); | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | return le32_to_cpu(data); | ||
341 | } | ||
342 | |||
250 | static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | 343 | static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, |
251 | struct usb_host_interface *alts, | 344 | struct usb_host_interface *alts, |
252 | struct audioformat *fmt, int rate) | 345 | struct audioformat *fmt, int rate) |
253 | { | 346 | { |
254 | struct usb_device *dev = chip->dev; | 347 | struct usb_device *dev = chip->dev; |
255 | unsigned char data[4]; | 348 | __le32 data; |
256 | int err, cur_rate, prev_rate; | 349 | int err, cur_rate, prev_rate; |
257 | int clock = snd_usb_clock_find_source(chip, fmt->clock); | 350 | int clock; |
351 | bool writeable; | ||
352 | struct uac_clock_source_descriptor *cs_desc; | ||
258 | 353 | ||
354 | clock = snd_usb_clock_find_source(chip, fmt->clock, true); | ||
259 | if (clock < 0) | 355 | if (clock < 0) |
260 | return clock; | 356 | return clock; |
261 | 357 | ||
262 | if (!uac_clock_source_is_valid(chip, clock)) { | 358 | prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); |
263 | /* TODO: should we try to find valid clock setups by ourself? */ | 359 | if (prev_rate == rate) |
264 | snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n", | 360 | return 0; |
265 | dev->devnum, iface, fmt->altsetting, clock); | ||
266 | return -ENXIO; | ||
267 | } | ||
268 | |||
269 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | ||
270 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
271 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
272 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
273 | data, sizeof(data)); | ||
274 | if (err < 0) { | ||
275 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | ||
276 | dev->devnum, iface, fmt->altsetting); | ||
277 | prev_rate = 0; | ||
278 | } else { | ||
279 | prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | ||
280 | } | ||
281 | 361 | ||
282 | data[0] = rate; | 362 | cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock); |
283 | data[1] = rate >> 8; | 363 | writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1); |
284 | data[2] = rate >> 16; | 364 | if (writeable) { |
285 | data[3] = rate >> 24; | 365 | data = cpu_to_le32(rate); |
286 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 366 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
287 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 367 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
288 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 368 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
289 | snd_usb_ctrl_intf(chip) | (clock << 8), | 369 | snd_usb_ctrl_intf(chip) | (clock << 8), |
290 | data, sizeof(data))) < 0) { | 370 | &data, sizeof(data)); |
291 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", | 371 | if (err < 0) { |
292 | dev->devnum, iface, fmt->altsetting, rate); | 372 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n", |
293 | return err; | 373 | dev->devnum, iface, fmt->altsetting, rate, err); |
294 | } | 374 | return err; |
375 | } | ||
295 | 376 | ||
296 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | 377 | cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); |
297 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
298 | UAC2_CS_CONTROL_SAM_FREQ << 8, | ||
299 | snd_usb_ctrl_intf(chip) | (clock << 8), | ||
300 | data, sizeof(data)); | ||
301 | if (err < 0) { | ||
302 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | ||
303 | dev->devnum, iface, fmt->altsetting); | ||
304 | cur_rate = 0; | ||
305 | } else { | 378 | } else { |
306 | cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | 379 | cur_rate = prev_rate; |
307 | } | 380 | } |
308 | 381 | ||
309 | if (cur_rate != rate) { | 382 | if (cur_rate != rate) { |
383 | if (!writeable) { | ||
384 | snd_printk(KERN_WARNING | ||
385 | "%d:%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n", | ||
386 | dev->devnum, iface, fmt->altsetting, rate, cur_rate); | ||
387 | return -ENXIO; | ||
388 | } | ||
310 | snd_printd(KERN_WARNING | 389 | snd_printd(KERN_WARNING |
311 | "current rate %d is different from the runtime rate %d\n", | 390 | "current rate %d is different from the runtime rate %d\n", |
312 | cur_rate, rate); | 391 | cur_rate, rate); |
@@ -316,7 +395,9 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
316 | * interface is active. */ | 395 | * interface is active. */ |
317 | if (rate != prev_rate) { | 396 | if (rate != prev_rate) { |
318 | usb_set_interface(dev, iface, 0); | 397 | usb_set_interface(dev, iface, 0); |
398 | snd_usb_set_interface_quirk(dev); | ||
319 | usb_set_interface(dev, iface, fmt->altsetting); | 399 | usb_set_interface(dev, iface, fmt->altsetting); |
400 | snd_usb_set_interface_quirk(dev); | ||
320 | } | 401 | } |
321 | 402 | ||
322 | return 0; | 403 | return 0; |
diff --git a/sound/usb/clock.h b/sound/usb/clock.h index 46630936d31f..d592e4a29856 100644 --- a/sound/usb/clock.h +++ b/sound/usb/clock.h | |||
@@ -5,6 +5,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
5 | struct usb_host_interface *alts, | 5 | struct usb_host_interface *alts, |
6 | struct audioformat *fmt, int rate); | 6 | struct audioformat *fmt, int rate); |
7 | 7 | ||
8 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id); | 8 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id, |
9 | bool validate); | ||
9 | 10 | ||
10 | #endif /* __USBAUDIO_CLOCK_H */ | 11 | #endif /* __USBAUDIO_CLOCK_H */ |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 21049b882ee6..7a444b5501d9 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -128,7 +128,7 @@ static const char *usb_error_string(int err) | |||
128 | * Determine whether an endpoint is driven by an implicit feedback | 128 | * Determine whether an endpoint is driven by an implicit feedback |
129 | * data endpoint source. | 129 | * data endpoint source. |
130 | */ | 130 | */ |
131 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) | 131 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep) |
132 | { | 132 | { |
133 | return ep->sync_master && | 133 | return ep->sync_master && |
134 | ep->sync_master->type == SND_USB_ENDPOINT_TYPE_DATA && | 134 | ep->sync_master->type == SND_USB_ENDPOINT_TYPE_DATA && |
@@ -363,7 +363,7 @@ static void snd_complete_urb(struct urb *urb) | |||
363 | if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) | 363 | if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) |
364 | goto exit_clear; | 364 | goto exit_clear; |
365 | 365 | ||
366 | if (snd_usb_endpoint_implict_feedback_sink(ep)) { | 366 | if (snd_usb_endpoint_implicit_feedback_sink(ep)) { |
367 | unsigned long flags; | 367 | unsigned long flags; |
368 | 368 | ||
369 | spin_lock_irqsave(&ep->lock, flags); | 369 | spin_lock_irqsave(&ep->lock, flags); |
@@ -415,14 +415,12 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
415 | struct usb_host_interface *alts, | 415 | struct usb_host_interface *alts, |
416 | int ep_num, int direction, int type) | 416 | int ep_num, int direction, int type) |
417 | { | 417 | { |
418 | struct list_head *p; | ||
419 | struct snd_usb_endpoint *ep; | 418 | struct snd_usb_endpoint *ep; |
420 | int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; | 419 | int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; |
421 | 420 | ||
422 | mutex_lock(&chip->mutex); | 421 | mutex_lock(&chip->mutex); |
423 | 422 | ||
424 | list_for_each(p, &chip->ep_list) { | 423 | list_for_each_entry(ep, &chip->ep_list, list) { |
425 | ep = list_entry(p, struct snd_usb_endpoint, list); | ||
426 | if (ep->ep_num == ep_num && | 424 | if (ep->ep_num == ep_num && |
427 | ep->iface == alts->desc.bInterfaceNumber && | 425 | ep->iface == alts->desc.bInterfaceNumber && |
428 | ep->alt_idx == alts->desc.bAlternateSetting) { | 426 | ep->alt_idx == alts->desc.bAlternateSetting) { |
@@ -580,6 +578,15 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
580 | int is_playback = usb_pipeout(ep->pipe); | 578 | int is_playback = usb_pipeout(ep->pipe); |
581 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; | 579 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; |
582 | 580 | ||
581 | if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) { | ||
582 | /* | ||
583 | * When operating in DSD DOP mode, the size of a sample frame | ||
584 | * in hardware differs from the actual physical format width | ||
585 | * because we need to make room for the DOP markers. | ||
586 | */ | ||
587 | frame_bits += channels << 3; | ||
588 | } | ||
589 | |||
583 | ep->datainterval = fmt->datainterval; | 590 | ep->datainterval = fmt->datainterval; |
584 | ep->stride = frame_bits >> 3; | 591 | ep->stride = frame_bits >> 3; |
585 | ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; | 592 | ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; |
@@ -607,7 +614,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
607 | else | 614 | else |
608 | packs_per_ms = 1; | 615 | packs_per_ms = 1; |
609 | 616 | ||
610 | if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { | 617 | if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { |
611 | urb_packs = max(ep->chip->nrpacks, 1); | 618 | urb_packs = max(ep->chip->nrpacks, 1); |
612 | urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); | 619 | urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); |
613 | } else { | 620 | } else { |
@@ -616,11 +623,11 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
616 | 623 | ||
617 | urb_packs *= packs_per_ms; | 624 | urb_packs *= packs_per_ms; |
618 | 625 | ||
619 | if (sync_ep && !snd_usb_endpoint_implict_feedback_sink(ep)) | 626 | if (sync_ep && !snd_usb_endpoint_implicit_feedback_sink(ep)) |
620 | urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); | 627 | urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); |
621 | 628 | ||
622 | /* decide how many packets to be used */ | 629 | /* decide how many packets to be used */ |
623 | if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { | 630 | if (is_playback && !snd_usb_endpoint_implicit_feedback_sink(ep)) { |
624 | unsigned int minsize, maxpacks; | 631 | unsigned int minsize, maxpacks; |
625 | /* determine how small a packet can be */ | 632 | /* determine how small a packet can be */ |
626 | minsize = (ep->freqn >> (16 - ep->datainterval)) | 633 | minsize = (ep->freqn >> (16 - ep->datainterval)) |
@@ -677,7 +684,7 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, | |||
677 | if (!u->urb->transfer_buffer) | 684 | if (!u->urb->transfer_buffer) |
678 | goto out_of_memory; | 685 | goto out_of_memory; |
679 | u->urb->pipe = ep->pipe; | 686 | u->urb->pipe = ep->pipe; |
680 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | 687 | u->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
681 | u->urb->interval = 1 << ep->datainterval; | 688 | u->urb->interval = 1 << ep->datainterval; |
682 | u->urb->context = u; | 689 | u->urb->context = u; |
683 | u->urb->complete = snd_complete_urb; | 690 | u->urb->complete = snd_complete_urb; |
@@ -716,8 +723,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep, | |||
716 | u->urb->transfer_dma = ep->sync_dma + i * 4; | 723 | u->urb->transfer_dma = ep->sync_dma + i * 4; |
717 | u->urb->transfer_buffer_length = 4; | 724 | u->urb->transfer_buffer_length = 4; |
718 | u->urb->pipe = ep->pipe; | 725 | u->urb->pipe = ep->pipe; |
719 | u->urb->transfer_flags = URB_ISO_ASAP | | 726 | u->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
720 | URB_NO_TRANSFER_DMA_MAP; | ||
721 | u->urb->number_of_packets = 1; | 727 | u->urb->number_of_packets = 1; |
722 | u->urb->interval = 1 << ep->syncinterval; | 728 | u->urb->interval = 1 << ep->syncinterval; |
723 | u->urb->context = u; | 729 | u->urb->context = u; |
@@ -847,7 +853,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) | |||
847 | 853 | ||
848 | set_bit(EP_FLAG_RUNNING, &ep->flags); | 854 | set_bit(EP_FLAG_RUNNING, &ep->flags); |
849 | 855 | ||
850 | if (snd_usb_endpoint_implict_feedback_sink(ep)) { | 856 | if (snd_usb_endpoint_implicit_feedback_sink(ep)) { |
851 | for (i = 0; i < ep->nurbs; i++) { | 857 | for (i = 0; i < ep->nurbs; i++) { |
852 | struct snd_urb_ctx *ctx = ep->urb + i; | 858 | struct snd_urb_ctx *ctx = ep->urb + i; |
853 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); | 859 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); |
@@ -990,7 +996,7 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
990 | * and add it to the list of pending urbs. queue_pending_output_urbs() | 996 | * and add it to the list of pending urbs. queue_pending_output_urbs() |
991 | * will take care of them later. | 997 | * will take care of them later. |
992 | */ | 998 | */ |
993 | if (snd_usb_endpoint_implict_feedback_sink(ep) && | 999 | if (snd_usb_endpoint_implicit_feedback_sink(ep) && |
994 | ep->use_count != 0) { | 1000 | ep->use_count != 0) { |
995 | 1001 | ||
996 | /* implicit feedback case */ | 1002 | /* implicit feedback case */ |
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 447902dd8a4a..2287adf5ca59 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
@@ -23,7 +23,7 @@ int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); | |||
23 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); | 23 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
24 | void snd_usb_endpoint_free(struct list_head *head); | 24 | void snd_usb_endpoint_free(struct list_head *head); |
25 | 25 | ||
26 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep); | 26 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); |
27 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); | 27 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); |
28 | 28 | ||
29 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | 29 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, |
diff --git a/sound/usb/format.c b/sound/usb/format.c index e831ee4238bb..99299ffb33ac 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -43,11 +43,11 @@ | |||
43 | */ | 43 | */ |
44 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | 44 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, |
45 | struct audioformat *fp, | 45 | struct audioformat *fp, |
46 | int format, void *_fmt, | 46 | unsigned int format, void *_fmt, |
47 | int protocol) | 47 | int protocol) |
48 | { | 48 | { |
49 | int sample_width, sample_bytes; | 49 | int sample_width, sample_bytes; |
50 | u64 pcm_formats; | 50 | u64 pcm_formats = 0; |
51 | 51 | ||
52 | switch (protocol) { | 52 | switch (protocol) { |
53 | case UAC_VERSION_1: | 53 | case UAC_VERSION_1: |
@@ -63,14 +63,17 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
63 | struct uac_format_type_i_ext_descriptor *fmt = _fmt; | 63 | struct uac_format_type_i_ext_descriptor *fmt = _fmt; |
64 | sample_width = fmt->bBitResolution; | 64 | sample_width = fmt->bBitResolution; |
65 | sample_bytes = fmt->bSubslotSize; | 65 | sample_bytes = fmt->bSubslotSize; |
66 | |||
67 | if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) | ||
68 | pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; | ||
69 | |||
66 | format <<= 1; | 70 | format <<= 1; |
67 | break; | 71 | break; |
68 | } | 72 | } |
69 | } | 73 | } |
70 | 74 | ||
71 | pcm_formats = 0; | 75 | if ((pcm_formats == 0) && |
72 | 76 | (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED))) { | |
73 | if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) { | ||
74 | /* some devices don't define this correctly... */ | 77 | /* some devices don't define this correctly... */ |
75 | snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", | 78 | snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", |
76 | chip->dev->devnum, fp->iface, fp->altsetting); | 79 | chip->dev->devnum, fp->iface, fp->altsetting); |
@@ -133,6 +136,9 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
133 | snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n", | 136 | snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n", |
134 | chip->dev->devnum, fp->iface, fp->altsetting, format); | 137 | chip->dev->devnum, fp->iface, fp->altsetting, format); |
135 | } | 138 | } |
139 | |||
140 | pcm_formats |= snd_usb_interface_dsd_format_quirks(chip, fp, sample_bytes); | ||
141 | |||
136 | return pcm_formats; | 142 | return pcm_formats; |
137 | } | 143 | } |
138 | 144 | ||
@@ -277,7 +283,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
277 | struct usb_device *dev = chip->dev; | 283 | struct usb_device *dev = chip->dev; |
278 | unsigned char tmp[2], *data; | 284 | unsigned char tmp[2], *data; |
279 | int nr_triplets, data_size, ret = 0; | 285 | int nr_triplets, data_size, ret = 0; |
280 | int clock = snd_usb_clock_find_source(chip, fp->clock); | 286 | int clock = snd_usb_clock_find_source(chip, fp->clock, false); |
281 | 287 | ||
282 | if (clock < 0) { | 288 | if (clock < 0) { |
283 | snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", | 289 | snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", |
@@ -353,13 +359,14 @@ err: | |||
353 | * parse the format type I and III descriptors | 359 | * parse the format type I and III descriptors |
354 | */ | 360 | */ |
355 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 361 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
356 | struct audioformat *fp, int format, | 362 | struct audioformat *fp, unsigned int format, |
357 | struct uac_format_type_i_continuous_descriptor *fmt, | 363 | struct uac_format_type_i_continuous_descriptor *fmt, |
358 | struct usb_host_interface *iface) | 364 | struct usb_host_interface *iface) |
359 | { | 365 | { |
360 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | 366 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
361 | int protocol = altsd->bInterfaceProtocol; | 367 | int protocol = altsd->bInterfaceProtocol; |
362 | int pcm_format, ret; | 368 | snd_pcm_format_t pcm_format; |
369 | int ret; | ||
363 | 370 | ||
364 | if (fmt->bFormatType == UAC_FORMAT_TYPE_III) { | 371 | if (fmt->bFormatType == UAC_FORMAT_TYPE_III) { |
365 | /* FIXME: the format type is really IECxxx | 372 | /* FIXME: the format type is really IECxxx |
@@ -378,7 +385,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
378 | default: | 385 | default: |
379 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; | 386 | pcm_format = SNDRV_PCM_FORMAT_S16_LE; |
380 | } | 387 | } |
381 | fp->formats = 1uLL << pcm_format; | 388 | fp->formats = pcm_format_to_bits(pcm_format); |
382 | } else { | 389 | } else { |
383 | fp->formats = parse_audio_format_i_type(chip, fp, format, | 390 | fp->formats = parse_audio_format_i_type(chip, fp, format, |
384 | fmt, protocol); | 391 | fmt, protocol); |
@@ -473,8 +480,9 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
473 | return ret; | 480 | return ret; |
474 | } | 481 | } |
475 | 482 | ||
476 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 483 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
477 | int format, struct uac_format_type_i_continuous_descriptor *fmt, | 484 | struct audioformat *fp, unsigned int format, |
485 | struct uac_format_type_i_continuous_descriptor *fmt, | ||
478 | int stream, struct usb_host_interface *iface) | 486 | int stream, struct usb_host_interface *iface) |
479 | { | 487 | { |
480 | int err; | 488 | int err; |
diff --git a/sound/usb/format.h b/sound/usb/format.h index 387924f0af85..6f315226f320 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define __USBAUDIO_FORMAT_H | 2 | #define __USBAUDIO_FORMAT_H |
3 | 3 | ||
4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | 4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
5 | struct audioformat *fp, int format, | 5 | struct audioformat *fp, unsigned int format, |
6 | struct uac_format_type_i_continuous_descriptor *fmt, | 6 | struct uac_format_type_i_continuous_descriptor *fmt, |
7 | int stream, struct usb_host_interface *iface); | 7 | int stream, struct usb_host_interface *iface); |
8 | 8 | ||
diff --git a/sound/usb/helper.c b/sound/usb/helper.c index c1db28f874c2..620902463c6e 100644 --- a/sound/usb/helper.c +++ b/sound/usb/helper.c | |||
@@ -86,14 +86,22 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, | |||
86 | { | 86 | { |
87 | int err; | 87 | int err; |
88 | void *buf = NULL; | 88 | void *buf = NULL; |
89 | int timeout; | ||
89 | 90 | ||
90 | if (size > 0) { | 91 | if (size > 0) { |
91 | buf = kmemdup(data, size, GFP_KERNEL); | 92 | buf = kmemdup(data, size, GFP_KERNEL); |
92 | if (!buf) | 93 | if (!buf) |
93 | return -ENOMEM; | 94 | return -ENOMEM; |
94 | } | 95 | } |
96 | |||
97 | if (requesttype & USB_DIR_IN) | ||
98 | timeout = USB_CTRL_GET_TIMEOUT; | ||
99 | else | ||
100 | timeout = USB_CTRL_SET_TIMEOUT; | ||
101 | |||
95 | err = usb_control_msg(dev, pipe, request, requesttype, | 102 | err = usb_control_msg(dev, pipe, request, requesttype, |
96 | value, index, buf, size, 1000); | 103 | value, index, buf, size, timeout); |
104 | |||
97 | if (size > 0) { | 105 | if (size > 0) { |
98 | memcpy(data, buf, size); | 106 | memcpy(data, buf, size); |
99 | kfree(buf); | 107 | kfree(buf); |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 34b9bb7fe87c..8e01fa4991c5 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -126,7 +126,6 @@ struct snd_usb_midi { | |||
126 | struct snd_usb_midi_in_endpoint *in; | 126 | struct snd_usb_midi_in_endpoint *in; |
127 | } endpoints[MIDI_MAX_ENDPOINTS]; | 127 | } endpoints[MIDI_MAX_ENDPOINTS]; |
128 | unsigned long input_triggered; | 128 | unsigned long input_triggered; |
129 | bool autopm_reference; | ||
130 | unsigned int opened[2]; | 129 | unsigned int opened[2]; |
131 | unsigned char disconnected; | 130 | unsigned char disconnected; |
132 | unsigned char input_running; | 131 | unsigned char input_running; |
@@ -1040,7 +1039,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, | |||
1040 | { | 1039 | { |
1041 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 1040 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1042 | struct snd_kcontrol *ctl; | 1041 | struct snd_kcontrol *ctl; |
1043 | int err; | ||
1044 | 1042 | ||
1045 | down_read(&umidi->disc_rwsem); | 1043 | down_read(&umidi->disc_rwsem); |
1046 | if (umidi->disconnected) { | 1044 | if (umidi->disconnected) { |
@@ -1051,13 +1049,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, | |||
1051 | mutex_lock(&umidi->mutex); | 1049 | mutex_lock(&umidi->mutex); |
1052 | if (open) { | 1050 | if (open) { |
1053 | if (!umidi->opened[0] && !umidi->opened[1]) { | 1051 | if (!umidi->opened[0] && !umidi->opened[1]) { |
1054 | err = usb_autopm_get_interface(umidi->iface); | ||
1055 | umidi->autopm_reference = err >= 0; | ||
1056 | if (err < 0 && err != -EACCES) { | ||
1057 | mutex_unlock(&umidi->mutex); | ||
1058 | up_read(&umidi->disc_rwsem); | ||
1059 | return -EIO; | ||
1060 | } | ||
1061 | if (umidi->roland_load_ctl) { | 1052 | if (umidi->roland_load_ctl) { |
1062 | ctl = umidi->roland_load_ctl; | 1053 | ctl = umidi->roland_load_ctl; |
1063 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | 1054 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
@@ -1080,8 +1071,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, | |||
1080 | snd_ctl_notify(umidi->card, | 1071 | snd_ctl_notify(umidi->card, |
1081 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | 1072 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); |
1082 | } | 1073 | } |
1083 | if (umidi->autopm_reference) | ||
1084 | usb_autopm_put_interface(umidi->iface); | ||
1085 | } | 1074 | } |
1086 | } | 1075 | } |
1087 | mutex_unlock(&umidi->mutex); | 1076 | mutex_unlock(&umidi->mutex); |
@@ -1455,6 +1444,7 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1455 | } | 1444 | } |
1456 | del_timer_sync(&umidi->error_timer); | 1445 | del_timer_sync(&umidi->error_timer); |
1457 | } | 1446 | } |
1447 | EXPORT_SYMBOL(snd_usbmidi_disconnect); | ||
1458 | 1448 | ||
1459 | static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi) | 1449 | static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi) |
1460 | { | 1450 | { |
@@ -1465,10 +1455,9 @@ static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi) | |||
1465 | static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi, | 1455 | static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi, |
1466 | int stream, int number) | 1456 | int stream, int number) |
1467 | { | 1457 | { |
1468 | struct list_head* list; | 1458 | struct snd_rawmidi_substream *substream; |
1469 | 1459 | ||
1470 | list_for_each(list, &umidi->rmidi->streams[stream].substreams) { | 1460 | list_for_each_entry(substream, &umidi->rmidi->streams[stream].substreams, list) { |
1471 | struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list); | ||
1472 | if (substream->number == number) | 1461 | if (substream->number == number) |
1473 | return substream; | 1462 | return substream; |
1474 | } | 1463 | } |
@@ -2091,6 +2080,7 @@ void snd_usbmidi_input_stop(struct list_head* p) | |||
2091 | } | 2080 | } |
2092 | umidi->input_running = 0; | 2081 | umidi->input_running = 0; |
2093 | } | 2082 | } |
2083 | EXPORT_SYMBOL(snd_usbmidi_input_stop); | ||
2094 | 2084 | ||
2095 | static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) | 2085 | static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) |
2096 | { | 2086 | { |
@@ -2120,6 +2110,7 @@ void snd_usbmidi_input_start(struct list_head* p) | |||
2120 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | 2110 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); |
2121 | umidi->input_running = 1; | 2111 | umidi->input_running = 1; |
2122 | } | 2112 | } |
2113 | EXPORT_SYMBOL(snd_usbmidi_input_start); | ||
2123 | 2114 | ||
2124 | /* | 2115 | /* |
2125 | * Creates and registers everything needed for a MIDI streaming interface. | 2116 | * Creates and registers everything needed for a MIDI streaming interface. |
@@ -2256,11 +2247,9 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2256 | return err; | 2247 | return err; |
2257 | } | 2248 | } |
2258 | 2249 | ||
2250 | usb_autopm_get_interface_no_resume(umidi->iface); | ||
2251 | |||
2259 | list_add_tail(&umidi->list, midi_list); | 2252 | list_add_tail(&umidi->list, midi_list); |
2260 | return 0; | 2253 | return 0; |
2261 | } | 2254 | } |
2262 | |||
2263 | EXPORT_SYMBOL(snd_usbmidi_create); | 2255 | EXPORT_SYMBOL(snd_usbmidi_create); |
2264 | EXPORT_SYMBOL(snd_usbmidi_input_stop); | ||
2265 | EXPORT_SYMBOL(snd_usbmidi_input_start); | ||
2266 | EXPORT_SYMBOL(snd_usbmidi_disconnect); | ||
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index 8b81cb54026f..6ad617b94732 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c | |||
@@ -1120,8 +1120,7 @@ static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream, | |||
1120 | usb_init_urb(&urb->urb); | 1120 | usb_init_urb(&urb->urb); |
1121 | urb->urb.dev = ua->dev; | 1121 | urb->urb.dev = ua->dev; |
1122 | urb->urb.pipe = stream->usb_pipe; | 1122 | urb->urb.pipe = stream->usb_pipe; |
1123 | urb->urb.transfer_flags = URB_ISO_ASAP | | 1123 | urb->urb.transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
1124 | URB_NO_TRANSFER_DMA_MAP; | ||
1125 | urb->urb.transfer_buffer = addr; | 1124 | urb->urb.transfer_buffer = addr; |
1126 | urb->urb.transfer_dma = dma; | 1125 | urb->urb.transfer_dma = dma; |
1127 | urb->urb.transfer_buffer_length = max_packet_size; | 1126 | urb->urb.transfer_buffer_length = max_packet_size; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index f94397b42aa5..93b6e32cfead 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/bitrev.h> | ||
19 | #include <linux/ratelimit.h> | 20 | #include <linux/ratelimit.h> |
20 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 22 | #include <linux/usb/audio.h> |
@@ -94,14 +95,12 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
94 | */ | 95 | */ |
95 | static struct audioformat *find_format(struct snd_usb_substream *subs) | 96 | static struct audioformat *find_format(struct snd_usb_substream *subs) |
96 | { | 97 | { |
97 | struct list_head *p; | 98 | struct audioformat *fp; |
98 | struct audioformat *found = NULL; | 99 | struct audioformat *found = NULL; |
99 | int cur_attr = 0, attr; | 100 | int cur_attr = 0, attr; |
100 | 101 | ||
101 | list_for_each(p, &subs->fmt_list) { | 102 | list_for_each_entry(fp, &subs->fmt_list, list) { |
102 | struct audioformat *fp; | 103 | if (!(fp->formats & pcm_format_to_bits(subs->pcm_format))) |
103 | fp = list_entry(p, struct audioformat, list); | ||
104 | if (!(fp->formats & (1uLL << subs->pcm_format))) | ||
105 | continue; | 104 | continue; |
106 | if (fp->channels != subs->channels) | 105 | if (fp->channels != subs->channels) |
107 | continue; | 106 | continue; |
@@ -350,6 +349,8 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
350 | fmt->iface, fmt->altsetting); | 349 | fmt->iface, fmt->altsetting); |
351 | subs->interface = fmt->iface; | 350 | subs->interface = fmt->iface; |
352 | subs->altset_idx = fmt->altset_idx; | 351 | subs->altset_idx = fmt->altset_idx; |
352 | |||
353 | snd_usb_set_interface_quirk(dev); | ||
353 | } | 354 | } |
354 | 355 | ||
355 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 356 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, |
@@ -477,7 +478,7 @@ static int match_endpoint_audioformats(struct audioformat *fp, | |||
477 | return 0; | 478 | return 0; |
478 | } | 479 | } |
479 | 480 | ||
480 | if (!(fp->formats & (1ULL << pcm_format))) { | 481 | if (!(fp->formats & pcm_format_to_bits(pcm_format))) { |
481 | snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__, | 482 | snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__, |
482 | fp, pcm_format); | 483 | fp, pcm_format); |
483 | return 0; | 484 | return 0; |
@@ -802,7 +803,7 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params, | |||
802 | struct snd_pcm_hw_rule *rule) | 803 | struct snd_pcm_hw_rule *rule) |
803 | { | 804 | { |
804 | struct snd_usb_substream *subs = rule->private; | 805 | struct snd_usb_substream *subs = rule->private; |
805 | struct list_head *p; | 806 | struct audioformat *fp; |
806 | struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 807 | struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
807 | unsigned int rmin, rmax; | 808 | unsigned int rmin, rmax; |
808 | int changed; | 809 | int changed; |
@@ -810,9 +811,7 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params, | |||
810 | hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max); | 811 | hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max); |
811 | changed = 0; | 812 | changed = 0; |
812 | rmin = rmax = 0; | 813 | rmin = rmax = 0; |
813 | list_for_each(p, &subs->fmt_list) { | 814 | list_for_each_entry(fp, &subs->fmt_list, list) { |
814 | struct audioformat *fp; | ||
815 | fp = list_entry(p, struct audioformat, list); | ||
816 | if (!hw_check_valid_format(subs, params, fp)) | 815 | if (!hw_check_valid_format(subs, params, fp)) |
817 | continue; | 816 | continue; |
818 | if (changed++) { | 817 | if (changed++) { |
@@ -856,7 +855,7 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, | |||
856 | struct snd_pcm_hw_rule *rule) | 855 | struct snd_pcm_hw_rule *rule) |
857 | { | 856 | { |
858 | struct snd_usb_substream *subs = rule->private; | 857 | struct snd_usb_substream *subs = rule->private; |
859 | struct list_head *p; | 858 | struct audioformat *fp; |
860 | struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 859 | struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
861 | unsigned int rmin, rmax; | 860 | unsigned int rmin, rmax; |
862 | int changed; | 861 | int changed; |
@@ -864,9 +863,7 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params, | |||
864 | hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max); | 863 | hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max); |
865 | changed = 0; | 864 | changed = 0; |
866 | rmin = rmax = 0; | 865 | rmin = rmax = 0; |
867 | list_for_each(p, &subs->fmt_list) { | 866 | list_for_each_entry(fp, &subs->fmt_list, list) { |
868 | struct audioformat *fp; | ||
869 | fp = list_entry(p, struct audioformat, list); | ||
870 | if (!hw_check_valid_format(subs, params, fp)) | 867 | if (!hw_check_valid_format(subs, params, fp)) |
871 | continue; | 868 | continue; |
872 | if (changed++) { | 869 | if (changed++) { |
@@ -909,7 +906,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params, | |||
909 | struct snd_pcm_hw_rule *rule) | 906 | struct snd_pcm_hw_rule *rule) |
910 | { | 907 | { |
911 | struct snd_usb_substream *subs = rule->private; | 908 | struct snd_usb_substream *subs = rule->private; |
912 | struct list_head *p; | 909 | struct audioformat *fp; |
913 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 910 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
914 | u64 fbits; | 911 | u64 fbits; |
915 | u32 oldbits[2]; | 912 | u32 oldbits[2]; |
@@ -917,9 +914,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params, | |||
917 | 914 | ||
918 | hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]); | 915 | hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]); |
919 | fbits = 0; | 916 | fbits = 0; |
920 | list_for_each(p, &subs->fmt_list) { | 917 | list_for_each_entry(fp, &subs->fmt_list, list) { |
921 | struct audioformat *fp; | ||
922 | fp = list_entry(p, struct audioformat, list); | ||
923 | if (!hw_check_valid_format(subs, params, fp)) | 918 | if (!hw_check_valid_format(subs, params, fp)) |
924 | continue; | 919 | continue; |
925 | fbits |= fp->formats; | 920 | fbits |= fp->formats; |
@@ -1027,7 +1022,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
1027 | 1022 | ||
1028 | static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs) | 1023 | static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs) |
1029 | { | 1024 | { |
1030 | struct list_head *p; | 1025 | struct audioformat *fp; |
1031 | unsigned int pt, ptmin; | 1026 | unsigned int pt, ptmin; |
1032 | int param_period_time_if_needed; | 1027 | int param_period_time_if_needed; |
1033 | int err; | 1028 | int err; |
@@ -1041,9 +1036,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1041 | runtime->hw.rates = 0; | 1036 | runtime->hw.rates = 0; |
1042 | ptmin = UINT_MAX; | 1037 | ptmin = UINT_MAX; |
1043 | /* check min/max rates and channels */ | 1038 | /* check min/max rates and channels */ |
1044 | list_for_each(p, &subs->fmt_list) { | 1039 | list_for_each_entry(fp, &subs->fmt_list, list) { |
1045 | struct audioformat *fp; | ||
1046 | fp = list_entry(p, struct audioformat, list); | ||
1047 | runtime->hw.rates |= fp->rates; | 1040 | runtime->hw.rates |= fp->rates; |
1048 | if (runtime->hw.rate_min > fp->rate_min) | 1041 | if (runtime->hw.rate_min > fp->rate_min) |
1049 | runtime->hw.rate_min = fp->rate_min; | 1042 | runtime->hw.rate_min = fp->rate_min; |
@@ -1128,6 +1121,12 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
1128 | runtime->private_data = subs; | 1121 | runtime->private_data = subs; |
1129 | subs->pcm_substream = substream; | 1122 | subs->pcm_substream = substream; |
1130 | /* runtime PM is also done there */ | 1123 | /* runtime PM is also done there */ |
1124 | |||
1125 | /* initialize DSD/DOP context */ | ||
1126 | subs->dsd_dop.byte_idx = 0; | ||
1127 | subs->dsd_dop.channel = 0; | ||
1128 | subs->dsd_dop.marker = 1; | ||
1129 | |||
1131 | return setup_hw_info(runtime, subs); | 1130 | return setup_hw_info(runtime, subs); |
1132 | } | 1131 | } |
1133 | 1132 | ||
@@ -1170,7 +1169,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1170 | stride = runtime->frame_bits >> 3; | 1169 | stride = runtime->frame_bits >> 3; |
1171 | 1170 | ||
1172 | for (i = 0; i < urb->number_of_packets; i++) { | 1171 | for (i = 0; i < urb->number_of_packets; i++) { |
1173 | cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 1172 | cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset + subs->pkt_offset_adj; |
1174 | if (urb->iso_frame_desc[i].status && printk_ratelimit()) { | 1173 | if (urb->iso_frame_desc[i].status && printk_ratelimit()) { |
1175 | snd_printdd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); | 1174 | snd_printdd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); |
1176 | // continue; | 1175 | // continue; |
@@ -1222,6 +1221,61 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1222 | snd_pcm_period_elapsed(subs->pcm_substream); | 1221 | snd_pcm_period_elapsed(subs->pcm_substream); |
1223 | } | 1222 | } |
1224 | 1223 | ||
1224 | static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs, | ||
1225 | struct urb *urb, unsigned int bytes) | ||
1226 | { | ||
1227 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | ||
1228 | unsigned int stride = runtime->frame_bits >> 3; | ||
1229 | unsigned int dst_idx = 0; | ||
1230 | unsigned int src_idx = subs->hwptr_done; | ||
1231 | unsigned int wrap = runtime->buffer_size * stride; | ||
1232 | u8 *dst = urb->transfer_buffer; | ||
1233 | u8 *src = runtime->dma_area; | ||
1234 | u8 marker[] = { 0x05, 0xfa }; | ||
1235 | |||
1236 | /* | ||
1237 | * The DSP DOP format defines a way to transport DSD samples over | ||
1238 | * normal PCM data endpoints. It requires stuffing of marker bytes | ||
1239 | * (0x05 and 0xfa, alternating per sample frame), and then expects | ||
1240 | * 2 additional bytes of actual payload. The whole frame is stored | ||
1241 | * LSB. | ||
1242 | * | ||
1243 | * Hence, for a stereo transport, the buffer layout looks like this, | ||
1244 | * where L refers to left channel samples and R to right. | ||
1245 | * | ||
1246 | * L1 L2 0x05 R1 R2 0x05 L3 L4 0xfa R3 R4 0xfa | ||
1247 | * L5 L6 0x05 R5 R6 0x05 L7 L8 0xfa R7 R8 0xfa | ||
1248 | * ..... | ||
1249 | * | ||
1250 | */ | ||
1251 | |||
1252 | while (bytes--) { | ||
1253 | if (++subs->dsd_dop.byte_idx == 3) { | ||
1254 | /* frame boundary? */ | ||
1255 | dst[dst_idx++] = marker[subs->dsd_dop.marker]; | ||
1256 | src_idx += 2; | ||
1257 | subs->dsd_dop.byte_idx = 0; | ||
1258 | |||
1259 | if (++subs->dsd_dop.channel % runtime->channels == 0) { | ||
1260 | /* alternate the marker */ | ||
1261 | subs->dsd_dop.marker++; | ||
1262 | subs->dsd_dop.marker %= ARRAY_SIZE(marker); | ||
1263 | subs->dsd_dop.channel = 0; | ||
1264 | } | ||
1265 | } else { | ||
1266 | /* stuff the DSD payload */ | ||
1267 | int idx = (src_idx + subs->dsd_dop.byte_idx - 1) % wrap; | ||
1268 | |||
1269 | if (subs->cur_audiofmt->dsd_bitrev) | ||
1270 | dst[dst_idx++] = bitrev8(src[idx]); | ||
1271 | else | ||
1272 | dst[dst_idx++] = src[idx]; | ||
1273 | |||
1274 | subs->hwptr_done++; | ||
1275 | } | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1225 | static void prepare_playback_urb(struct snd_usb_substream *subs, | 1279 | static void prepare_playback_urb(struct snd_usb_substream *subs, |
1226 | struct urb *urb) | 1280 | struct urb *urb) |
1227 | { | 1281 | { |
@@ -1244,8 +1298,8 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1244 | counts = snd_usb_endpoint_next_packet_size(ep); | 1298 | counts = snd_usb_endpoint_next_packet_size(ep); |
1245 | 1299 | ||
1246 | /* set up descriptor */ | 1300 | /* set up descriptor */ |
1247 | urb->iso_frame_desc[i].offset = frames * stride; | 1301 | urb->iso_frame_desc[i].offset = frames * ep->stride; |
1248 | urb->iso_frame_desc[i].length = counts * stride; | 1302 | urb->iso_frame_desc[i].length = counts * ep->stride; |
1249 | frames += counts; | 1303 | frames += counts; |
1250 | urb->number_of_packets++; | 1304 | urb->number_of_packets++; |
1251 | subs->transfer_done += counts; | 1305 | subs->transfer_done += counts; |
@@ -1259,14 +1313,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1259 | frames -= subs->transfer_done; | 1313 | frames -= subs->transfer_done; |
1260 | counts -= subs->transfer_done; | 1314 | counts -= subs->transfer_done; |
1261 | urb->iso_frame_desc[i].length = | 1315 | urb->iso_frame_desc[i].length = |
1262 | counts * stride; | 1316 | counts * ep->stride; |
1263 | subs->transfer_done = 0; | 1317 | subs->transfer_done = 0; |
1264 | } | 1318 | } |
1265 | i++; | 1319 | i++; |
1266 | if (i < ctx->packets) { | 1320 | if (i < ctx->packets) { |
1267 | /* add a transfer delimiter */ | 1321 | /* add a transfer delimiter */ |
1268 | urb->iso_frame_desc[i].offset = | 1322 | urb->iso_frame_desc[i].offset = |
1269 | frames * stride; | 1323 | frames * ep->stride; |
1270 | urb->iso_frame_desc[i].length = 0; | 1324 | urb->iso_frame_desc[i].length = 0; |
1271 | urb->number_of_packets++; | 1325 | urb->number_of_packets++; |
1272 | } | 1326 | } |
@@ -1274,23 +1328,43 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1274 | } | 1328 | } |
1275 | } | 1329 | } |
1276 | if (period_elapsed && | 1330 | if (period_elapsed && |
1277 | !snd_usb_endpoint_implict_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ | 1331 | !snd_usb_endpoint_implicit_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ |
1278 | break; | 1332 | break; |
1279 | } | 1333 | } |
1280 | bytes = frames * stride; | 1334 | bytes = frames * ep->stride; |
1281 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { | 1335 | |
1282 | /* err, the transferred area goes over buffer boundary. */ | 1336 | if (unlikely(subs->pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && |
1283 | unsigned int bytes1 = | 1337 | subs->cur_audiofmt->dsd_dop)) { |
1284 | runtime->buffer_size * stride - subs->hwptr_done; | 1338 | fill_playback_urb_dsd_dop(subs, urb, bytes); |
1285 | memcpy(urb->transfer_buffer, | 1339 | } else if (unlikely(subs->pcm_format == SNDRV_PCM_FORMAT_DSD_U8 && |
1286 | runtime->dma_area + subs->hwptr_done, bytes1); | 1340 | subs->cur_audiofmt->dsd_bitrev)) { |
1287 | memcpy(urb->transfer_buffer + bytes1, | 1341 | /* bit-reverse the bytes */ |
1288 | runtime->dma_area, bytes - bytes1); | 1342 | u8 *buf = urb->transfer_buffer; |
1343 | for (i = 0; i < bytes; i++) { | ||
1344 | int idx = (subs->hwptr_done + i) | ||
1345 | % (runtime->buffer_size * stride); | ||
1346 | buf[i] = bitrev8(runtime->dma_area[idx]); | ||
1347 | } | ||
1348 | |||
1349 | subs->hwptr_done += bytes; | ||
1289 | } else { | 1350 | } else { |
1290 | memcpy(urb->transfer_buffer, | 1351 | /* usual PCM */ |
1291 | runtime->dma_area + subs->hwptr_done, bytes); | 1352 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { |
1353 | /* err, the transferred area goes over buffer boundary. */ | ||
1354 | unsigned int bytes1 = | ||
1355 | runtime->buffer_size * stride - subs->hwptr_done; | ||
1356 | memcpy(urb->transfer_buffer, | ||
1357 | runtime->dma_area + subs->hwptr_done, bytes1); | ||
1358 | memcpy(urb->transfer_buffer + bytes1, | ||
1359 | runtime->dma_area, bytes - bytes1); | ||
1360 | } else { | ||
1361 | memcpy(urb->transfer_buffer, | ||
1362 | runtime->dma_area + subs->hwptr_done, bytes); | ||
1363 | } | ||
1364 | |||
1365 | subs->hwptr_done += bytes; | ||
1292 | } | 1366 | } |
1293 | subs->hwptr_done += bytes; | 1367 | |
1294 | if (subs->hwptr_done >= runtime->buffer_size * stride) | 1368 | if (subs->hwptr_done >= runtime->buffer_size * stride) |
1295 | subs->hwptr_done -= runtime->buffer_size * stride; | 1369 | subs->hwptr_done -= runtime->buffer_size * stride; |
1296 | 1370 | ||
@@ -1318,8 +1392,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs, | |||
1318 | { | 1392 | { |
1319 | unsigned long flags; | 1393 | unsigned long flags; |
1320 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | 1394 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; |
1321 | int stride = runtime->frame_bits >> 3; | 1395 | struct snd_usb_endpoint *ep = subs->data_endpoint; |
1322 | int processed = urb->transfer_buffer_length / stride; | 1396 | int processed = urb->transfer_buffer_length / ep->stride; |
1323 | int est_delay; | 1397 | int est_delay; |
1324 | 1398 | ||
1325 | /* ignore the delay accounting when procssed=0 is given, i.e. | 1399 | /* ignore the delay accounting when procssed=0 is given, i.e. |
diff --git a/sound/usb/proc.c b/sound/usb/proc.c index d218f763501f..135c76871063 100644 --- a/sound/usb/proc.c +++ b/sound/usb/proc.c | |||
@@ -73,20 +73,19 @@ void snd_usb_audio_create_proc(struct snd_usb_audio *chip) | |||
73 | */ | 73 | */ |
74 | static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer) | 74 | static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer) |
75 | { | 75 | { |
76 | struct list_head *p; | 76 | struct audioformat *fp; |
77 | static char *sync_types[4] = { | 77 | static char *sync_types[4] = { |
78 | "NONE", "ASYNC", "ADAPTIVE", "SYNC" | 78 | "NONE", "ASYNC", "ADAPTIVE", "SYNC" |
79 | }; | 79 | }; |
80 | 80 | ||
81 | list_for_each(p, &subs->fmt_list) { | 81 | list_for_each_entry(fp, &subs->fmt_list, list) { |
82 | struct audioformat *fp; | ||
83 | snd_pcm_format_t fmt; | 82 | snd_pcm_format_t fmt; |
84 | fp = list_entry(p, struct audioformat, list); | 83 | |
85 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 84 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
86 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 85 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
87 | snd_iprintf(buffer, " Format:"); | 86 | snd_iprintf(buffer, " Format:"); |
88 | for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt) | 87 | for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt) |
89 | if (fp->formats & (1uLL << fmt)) | 88 | if (fp->formats & pcm_format_to_bits(fmt)) |
90 | snd_iprintf(buffer, " %s", | 89 | snd_iprintf(buffer, " %s", |
91 | snd_pcm_format_name(fmt)); | 90 | snd_pcm_format_name(fmt)); |
92 | snd_iprintf(buffer, "\n"); | 91 | snd_iprintf(buffer, "\n"); |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index c39f898b15d2..7f1722f82c89 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -353,6 +353,84 @@ YAMAHA_DEVICE(0x105d, NULL), | |||
353 | } | 353 | } |
354 | } | 354 | } |
355 | }, | 355 | }, |
356 | { | ||
357 | USB_DEVICE(0x0499, 0x1507), | ||
358 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
359 | /* .vendor_name = "Yamaha", */ | ||
360 | /* .product_name = "THR10", */ | ||
361 | .ifnum = QUIRK_ANY_INTERFACE, | ||
362 | .type = QUIRK_COMPOSITE, | ||
363 | .data = (const struct snd_usb_audio_quirk[]) { | ||
364 | { | ||
365 | .ifnum = 1, | ||
366 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
367 | }, | ||
368 | { | ||
369 | .ifnum = 2, | ||
370 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
371 | }, | ||
372 | { | ||
373 | .ifnum = 3, | ||
374 | .type = QUIRK_MIDI_YAMAHA | ||
375 | }, | ||
376 | { | ||
377 | .ifnum = -1 | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | }, | ||
382 | { | ||
383 | USB_DEVICE(0x0499, 0x150a), | ||
384 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
385 | /* .vendor_name = "Yamaha", */ | ||
386 | /* .product_name = "THR5A", */ | ||
387 | .ifnum = QUIRK_ANY_INTERFACE, | ||
388 | .type = QUIRK_COMPOSITE, | ||
389 | .data = (const struct snd_usb_audio_quirk[]) { | ||
390 | { | ||
391 | .ifnum = 1, | ||
392 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
393 | }, | ||
394 | { | ||
395 | .ifnum = 2, | ||
396 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
397 | }, | ||
398 | { | ||
399 | .ifnum = 3, | ||
400 | .type = QUIRK_MIDI_YAMAHA | ||
401 | }, | ||
402 | { | ||
403 | .ifnum = -1 | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | }, | ||
408 | { | ||
409 | USB_DEVICE(0x0499, 0x150c), | ||
410 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
411 | /* .vendor_name = "Yamaha", */ | ||
412 | /* .product_name = "THR10C", */ | ||
413 | .ifnum = QUIRK_ANY_INTERFACE, | ||
414 | .type = QUIRK_COMPOSITE, | ||
415 | .data = (const struct snd_usb_audio_quirk[]) { | ||
416 | { | ||
417 | .ifnum = 1, | ||
418 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
419 | }, | ||
420 | { | ||
421 | .ifnum = 2, | ||
422 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
423 | }, | ||
424 | { | ||
425 | .ifnum = 3, | ||
426 | .type = QUIRK_MIDI_YAMAHA | ||
427 | }, | ||
428 | { | ||
429 | .ifnum = -1 | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | }, | ||
356 | YAMAHA_DEVICE(0x2000, "DGP-7"), | 434 | YAMAHA_DEVICE(0x2000, "DGP-7"), |
357 | YAMAHA_DEVICE(0x2001, "DGP-5"), | 435 | YAMAHA_DEVICE(0x2001, "DGP-5"), |
358 | YAMAHA_DEVICE(0x2002, NULL), | 436 | YAMAHA_DEVICE(0x2002, NULL), |
@@ -2748,6 +2826,46 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2748 | } | 2826 | } |
2749 | }, | 2827 | }, |
2750 | { | 2828 | { |
2829 | USB_DEVICE(0x1235, 0x0018), | ||
2830 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
2831 | .vendor_name = "Novation", | ||
2832 | .product_name = "Twitch", | ||
2833 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2834 | .type = QUIRK_COMPOSITE, | ||
2835 | .data = (const struct snd_usb_audio_quirk[]) { | ||
2836 | { | ||
2837 | .ifnum = 0, | ||
2838 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2839 | .data = & (const struct audioformat) { | ||
2840 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
2841 | .channels = 4, | ||
2842 | .iface = 0, | ||
2843 | .altsetting = 1, | ||
2844 | .altset_idx = 1, | ||
2845 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
2846 | .endpoint = 0x01, | ||
2847 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
2848 | .rates = SNDRV_PCM_RATE_44100 | | ||
2849 | SNDRV_PCM_RATE_48000, | ||
2850 | .rate_min = 44100, | ||
2851 | .rate_max = 48000, | ||
2852 | .nr_rates = 2, | ||
2853 | .rate_table = (unsigned int[]) { | ||
2854 | 44100, 48000 | ||
2855 | } | ||
2856 | } | ||
2857 | }, | ||
2858 | { | ||
2859 | .ifnum = 1, | ||
2860 | .type = QUIRK_MIDI_RAW_BYTES | ||
2861 | }, | ||
2862 | { | ||
2863 | .ifnum = -1 | ||
2864 | } | ||
2865 | } | ||
2866 | } | ||
2867 | }, | ||
2868 | { | ||
2751 | USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661), | 2869 | USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661), |
2752 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 2870 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
2753 | .vendor_name = "Novation", | 2871 | .vendor_name = "Novation", |
@@ -2996,7 +3114,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2996 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | 3114 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, |
2997 | .endpoint = 0x02, | 3115 | .endpoint = 0x02, |
2998 | .ep_attr = 0x01, | 3116 | .ep_attr = 0x01, |
2999 | .maxpacksize = 0x130, | ||
3000 | .rates = SNDRV_PCM_RATE_44100 | | 3117 | .rates = SNDRV_PCM_RATE_44100 | |
3001 | SNDRV_PCM_RATE_48000, | 3118 | SNDRV_PCM_RATE_48000, |
3002 | .rate_min = 44100, | 3119 | .rate_min = 44100, |
@@ -3044,7 +3161,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
3044 | .attributes = 0x00, | 3161 | .attributes = 0x00, |
3045 | .endpoint = 0x03, | 3162 | .endpoint = 0x03, |
3046 | .ep_attr = USB_ENDPOINT_SYNC_ASYNC, | 3163 | .ep_attr = USB_ENDPOINT_SYNC_ASYNC, |
3047 | .maxpacksize = 0x128, | ||
3048 | .rates = SNDRV_PCM_RATE_48000, | 3164 | .rates = SNDRV_PCM_RATE_48000, |
3049 | .rate_min = 48000, | 3165 | .rate_min = 48000, |
3050 | .rate_max = 48000, | 3166 | .rate_max = 48000, |
@@ -3070,7 +3186,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
3070 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | 3186 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, |
3071 | .endpoint = 0x85, | 3187 | .endpoint = 0x85, |
3072 | .ep_attr = USB_ENDPOINT_SYNC_SYNC, | 3188 | .ep_attr = USB_ENDPOINT_SYNC_SYNC, |
3073 | .maxpacksize = 0x128, | ||
3074 | .rates = SNDRV_PCM_RATE_48000, | 3189 | .rates = SNDRV_PCM_RATE_48000, |
3075 | .rate_min = 48000, | 3190 | .rate_min = 48000, |
3076 | .rate_max = 48000, | 3191 | .rate_max = 48000, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 9c5ab22358b1..3879eae7e874 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -165,8 +165,10 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
165 | return -EINVAL; | 165 | return -EINVAL; |
166 | } | 166 | } |
167 | alts = &iface->altsetting[fp->altset_idx]; | 167 | alts = &iface->altsetting[fp->altset_idx]; |
168 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | 168 | if (fp->datainterval == 0) |
169 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 169 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); |
170 | if (fp->maxpacksize == 0) | ||
171 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
170 | usb_set_interface(chip->dev, fp->iface, 0); | 172 | usb_set_interface(chip->dev, fp->iface, 0); |
171 | snd_usb_init_pitch(chip, fp->iface, alts, fp); | 173 | snd_usb_init_pitch(chip, fp->iface, alts, fp); |
172 | snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max); | 174 | snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max); |
@@ -446,6 +448,17 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | |||
446 | } | 448 | } |
447 | 449 | ||
448 | /* | 450 | /* |
451 | * Novation Twitch DJ controller | ||
452 | */ | ||
453 | static int snd_usb_twitch_boot_quirk(struct usb_device *dev) | ||
454 | { | ||
455 | /* preemptively set up the device because otherwise the | ||
456 | * raw MIDI endpoints are not active */ | ||
457 | usb_set_interface(dev, 0, 1); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | /* | ||
449 | * This call will put the synth in "USB send" mode, i.e it will send MIDI | 462 | * This call will put the synth in "USB send" mode, i.e it will send MIDI |
450 | * messages through USB (this is disabled at startup). The synth will | 463 | * messages through USB (this is disabled at startup). The synth will |
451 | * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB | 464 | * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB |
@@ -746,6 +759,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
746 | /* Digidesign Mbox 2 */ | 759 | /* Digidesign Mbox 2 */ |
747 | return snd_usb_mbox2_boot_quirk(dev); | 760 | return snd_usb_mbox2_boot_quirk(dev); |
748 | 761 | ||
762 | case USB_ID(0x1235, 0x0018): | ||
763 | /* Focusrite Novation Twitch */ | ||
764 | return snd_usb_twitch_boot_quirk(dev); | ||
765 | |||
749 | case USB_ID(0x133e, 0x0815): | 766 | case USB_ID(0x133e, 0x0815): |
750 | /* Access Music VirusTI Desktop */ | 767 | /* Access Music VirusTI Desktop */ |
751 | return snd_usb_accessmusic_boot_quirk(dev); | 768 | return snd_usb_accessmusic_boot_quirk(dev); |
@@ -837,6 +854,7 @@ static void set_format_emu_quirk(struct snd_usb_substream *subs, | |||
837 | break; | 854 | break; |
838 | } | 855 | } |
839 | snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id); | 856 | snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id); |
857 | subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0; | ||
840 | } | 858 | } |
841 | 859 | ||
842 | void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | 860 | void snd_usb_set_format_quirk(struct snd_usb_substream *subs, |
@@ -875,6 +893,16 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | |||
875 | ep->skip_packets = 16; | 893 | ep->skip_packets = 16; |
876 | } | 894 | } |
877 | 895 | ||
896 | void snd_usb_set_interface_quirk(struct usb_device *dev) | ||
897 | { | ||
898 | /* | ||
899 | * "Playback Design" products need a 50ms delay after setting the | ||
900 | * USB interface. | ||
901 | */ | ||
902 | if (le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) | ||
903 | mdelay(50); | ||
904 | } | ||
905 | |||
878 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | 906 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, |
879 | __u8 request, __u8 requesttype, __u16 value, | 907 | __u8 request, __u8 requesttype, __u16 value, |
880 | __u16 index, void *data, __u16 size) | 908 | __u16 index, void *data, __u16 size) |
@@ -888,3 +916,31 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | |||
888 | mdelay(20); | 916 | mdelay(20); |
889 | } | 917 | } |
890 | 918 | ||
919 | /* | ||
920 | * snd_usb_interface_dsd_format_quirks() is called from format.c to | ||
921 | * augment the PCM format bit-field for DSD types. The UAC standards | ||
922 | * don't have a designated bit field to denote DSD-capable interfaces, | ||
923 | * hence all hardware that is known to support this format has to be | ||
924 | * listed here. | ||
925 | */ | ||
926 | u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | ||
927 | struct audioformat *fp, | ||
928 | unsigned int sample_bytes) | ||
929 | { | ||
930 | /* Playback Designs */ | ||
931 | if (le16_to_cpu(chip->dev->descriptor.idVendor) == 0x23ba) { | ||
932 | switch (fp->altsetting) { | ||
933 | case 1: | ||
934 | fp->dsd_dop = true; | ||
935 | return SNDRV_PCM_FMTBIT_DSD_U16_LE; | ||
936 | case 2: | ||
937 | fp->dsd_bitrev = true; | ||
938 | return SNDRV_PCM_FMTBIT_DSD_U8; | ||
939 | case 3: | ||
940 | fp->dsd_bitrev = true; | ||
941 | return SNDRV_PCM_FMTBIT_DSD_U16_LE; | ||
942 | } | ||
943 | } | ||
944 | |||
945 | return 0; | ||
946 | } | ||
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 0ca9e91067a6..665e972a1b40 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h | |||
@@ -26,8 +26,13 @@ int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, | |||
26 | 26 | ||
27 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep); | 27 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep); |
28 | 28 | ||
29 | void snd_usb_set_interface_quirk(struct usb_device *dev); | ||
29 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | 30 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, |
30 | __u8 request, __u8 requesttype, __u16 value, | 31 | __u8 request, __u8 requesttype, __u16 value, |
31 | __u16 index, void *data, __u16 size); | 32 | __u16 index, void *data, __u16 size); |
32 | 33 | ||
34 | u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | ||
35 | struct audioformat *fp, | ||
36 | unsigned int sample_bytes); | ||
37 | |||
33 | #endif /* __USBAUDIO_QUIRKS_H */ | 38 | #endif /* __USBAUDIO_QUIRKS_H */ |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index ad181d538bd9..7db2f8958e79 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
@@ -42,12 +42,11 @@ | |||
42 | */ | 42 | */ |
43 | static void free_substream(struct snd_usb_substream *subs) | 43 | static void free_substream(struct snd_usb_substream *subs) |
44 | { | 44 | { |
45 | struct list_head *p, *n; | 45 | struct audioformat *fp, *n; |
46 | 46 | ||
47 | if (!subs->num_formats) | 47 | if (!subs->num_formats) |
48 | return; /* not initialized */ | 48 | return; /* not initialized */ |
49 | list_for_each_safe(p, n, &subs->fmt_list) { | 49 | list_for_each_entry_safe(fp, n, &subs->fmt_list, list) { |
50 | struct audioformat *fp = list_entry(p, struct audioformat, list); | ||
51 | kfree(fp->rate_table); | 50 | kfree(fp->rate_table); |
52 | kfree(fp->chmap); | 51 | kfree(fp->chmap); |
53 | kfree(fp); | 52 | kfree(fp); |
@@ -94,6 +93,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as, | |||
94 | subs->dev = as->chip->dev; | 93 | subs->dev = as->chip->dev; |
95 | subs->txfr_quirk = as->chip->txfr_quirk; | 94 | subs->txfr_quirk = as->chip->txfr_quirk; |
96 | subs->speed = snd_usb_get_speed(subs->dev); | 95 | subs->speed = snd_usb_get_speed(subs->dev); |
96 | subs->pkt_offset_adj = 0; | ||
97 | 97 | ||
98 | snd_usb_set_pcm_ops(as->pcm, stream); | 98 | snd_usb_set_pcm_ops(as->pcm, stream); |
99 | 99 | ||
@@ -313,14 +313,12 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | |||
313 | int stream, | 313 | int stream, |
314 | struct audioformat *fp) | 314 | struct audioformat *fp) |
315 | { | 315 | { |
316 | struct list_head *p; | ||
317 | struct snd_usb_stream *as; | 316 | struct snd_usb_stream *as; |
318 | struct snd_usb_substream *subs; | 317 | struct snd_usb_substream *subs; |
319 | struct snd_pcm *pcm; | 318 | struct snd_pcm *pcm; |
320 | int err; | 319 | int err; |
321 | 320 | ||
322 | list_for_each(p, &chip->pcm_list) { | 321 | list_for_each_entry(as, &chip->pcm_list, list) { |
323 | as = list_entry(p, struct snd_usb_stream, list); | ||
324 | if (as->fmt_type != fp->fmt_type) | 322 | if (as->fmt_type != fp->fmt_type) |
325 | continue; | 323 | continue; |
326 | subs = &as->substream[stream]; | 324 | subs = &as->substream[stream]; |
@@ -332,8 +330,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | |||
332 | } | 330 | } |
333 | } | 331 | } |
334 | /* look for an empty stream */ | 332 | /* look for an empty stream */ |
335 | list_for_each(p, &chip->pcm_list) { | 333 | list_for_each_entry(as, &chip->pcm_list, list) { |
336 | as = list_entry(p, struct snd_usb_stream, list); | ||
337 | if (as->fmt_type != fp->fmt_type) | 334 | if (as->fmt_type != fp->fmt_type) |
338 | continue; | 335 | continue; |
339 | subs = &as->substream[stream]; | 336 | subs = &as->substream[stream]; |
@@ -396,6 +393,14 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | |||
396 | if (!csep && altsd->bNumEndpoints >= 2) | 393 | if (!csep && altsd->bNumEndpoints >= 2) |
397 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | 394 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); |
398 | 395 | ||
396 | /* | ||
397 | * If we can't locate the USB_DT_CS_ENDPOINT descriptor in the extra | ||
398 | * bytes after the first endpoint, go search the entire interface. | ||
399 | * Some devices have it directly *before* the standard endpoint. | ||
400 | */ | ||
401 | if (!csep) | ||
402 | csep = snd_usb_find_desc(alts->extra, alts->extralen, NULL, USB_DT_CS_ENDPOINT); | ||
403 | |||
399 | if (!csep || csep->bLength < 7 || | 404 | if (!csep || csep->bLength < 7 || |
400 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | 405 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { |
401 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | 406 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" |
@@ -463,7 +468,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
463 | struct usb_host_interface *alts; | 468 | struct usb_host_interface *alts; |
464 | struct usb_interface_descriptor *altsd; | 469 | struct usb_interface_descriptor *altsd; |
465 | int i, altno, err, stream; | 470 | int i, altno, err, stream; |
466 | int format = 0, num_channels = 0; | 471 | unsigned int format = 0, num_channels = 0; |
467 | struct audioformat *fp = NULL; | 472 | struct audioformat *fp = NULL; |
468 | int num, protocol, clock = 0; | 473 | int num, protocol, clock = 0; |
469 | struct uac_format_type_i_continuous_descriptor *fmt; | 474 | struct uac_format_type_i_continuous_descriptor *fmt; |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1ac3fd9cc5a6..bc43bcaddf4d 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -56,6 +56,7 @@ struct snd_usb_audio { | |||
56 | 56 | ||
57 | int setup; /* from the 'device_setup' module param */ | 57 | int setup; /* from the 'device_setup' module param */ |
58 | int nrpacks; /* from the 'nrpacks' module param */ | 58 | int nrpacks; /* from the 'nrpacks' module param */ |
59 | bool autoclock; /* from the 'autoclock' module param */ | ||
59 | 60 | ||
60 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | 61 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ |
61 | }; | 62 | }; |
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index 1e7a47a86605..bf618e1500ac 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c | |||
@@ -69,7 +69,6 @@ static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, | |||
69 | ++u, transfer += transfer_length) { | 69 | ++u, transfer += transfer_length) { |
70 | struct urb *urb = urbs[u]; | 70 | struct urb *urb = urbs[u]; |
71 | struct usb_iso_packet_descriptor *desc; | 71 | struct usb_iso_packet_descriptor *desc; |
72 | urb->transfer_flags = URB_ISO_ASAP; | ||
73 | urb->transfer_buffer = transfer; | 72 | urb->transfer_buffer = transfer; |
74 | urb->dev = dev; | 73 | urb->dev = dev; |
75 | urb->pipe = pipe; | 74 | urb->pipe = pipe; |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 520ef96d7c75..b37653247ef4 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -503,7 +503,6 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs) | |||
503 | if (0 == i) | 503 | if (0 == i) |
504 | atomic_set(&subs->state, state_STARTING3); | 504 | atomic_set(&subs->state, state_STARTING3); |
505 | urb->dev = usX2Y->dev; | 505 | urb->dev = usX2Y->dev; |
506 | urb->transfer_flags = URB_ISO_ASAP; | ||
507 | for (pack = 0; pack < nr_of_packs(); pack++) { | 506 | for (pack = 0; pack < nr_of_packs(); pack++) { |
508 | urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; | 507 | urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; |
509 | urb->iso_frame_desc[pack].length = subs->maxpacksize; | 508 | urb->iso_frame_desc[pack].length = subs->maxpacksize; |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index cc56007791e0..f2a1acdc4d83 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
@@ -443,7 +443,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs) | |||
443 | if (0 == u) | 443 | if (0 == u) |
444 | atomic_set(&subs->state, state_STARTING3); | 444 | atomic_set(&subs->state, state_STARTING3); |
445 | urb->dev = usX2Y->dev; | 445 | urb->dev = usX2Y->dev; |
446 | urb->transfer_flags = URB_ISO_ASAP; | ||
447 | for (pack = 0; pack < nr_of_packs(); pack++) { | 446 | for (pack = 0; pack < nr_of_packs(); pack++) { |
448 | urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); | 447 | urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); |
449 | urb->iso_frame_desc[pack].length = subs->maxpacksize; | 448 | urb->iso_frame_desc[pack].length = subs->maxpacksize; |