diff options
Diffstat (limited to 'sound')
47 files changed, 506 insertions, 238 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index 051d55b05521..9f404e965ea2 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -684,7 +684,7 @@ int snd_info_card_free(struct snd_card *card) * snd_info_get_line - read one line from the procfs buffer * @buffer: the procfs buffer * @line: the buffer to store - * @len: the max. buffer size - 1 + * @len: the max. buffer size * * Reads one line from the buffer and stores the string. * @@ -704,7 +704,7 @@ int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len) buffer->stop = 1; if (c == '\n') break; - if (len) { + if (len > 1) { len--; *line++ = c; } diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 9acc77eae487..0032278567ad 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1782,14 +1782,16 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, { struct snd_pcm_hw_params *params = arg; snd_pcm_format_t format; - int channels, width; + int channels; + ssize_t frame_size; params->fifo_size = substream->runtime->hw.fifo_size; if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) { format = params_format(params); channels = params_channels(params); - width = snd_pcm_format_physical_width(format); - params->fifo_size /= width * channels; + frame_size = snd_pcm_format_size(format, channels); + if (frame_size > 0) + params->fifo_size /= (unsigned)frame_size; } return 0; } diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 4560ca0e5651..2c6fd80e0bd1 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -142,11 +142,11 @@ static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { }, [SNDRV_PCM_FORMAT_DSD_U8] = { .width = 8, .phys = 8, .le = 1, .signd = 0, - .silence = {}, + .silence = { 0x69 }, }, [SNDRV_PCM_FORMAT_DSD_U16_LE] = { .width = 16, .phys = 16, .le = 1, .signd = 0, - .silence = {}, + .silence = { 0x69, 0x69 }, }, /* FIXME: the following three formats are not defined properly yet */ [SNDRV_PCM_FORMAT_MPEG] = { diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index f96bf4c7c232..95fc2eaf11dc 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -507,7 +507,16 @@ static void amdtp_pull_midi(struct amdtp_stream *s, static void update_pcm_pointers(struct amdtp_stream *s, struct snd_pcm_substream *pcm, unsigned int frames) -{ unsigned int ptr; +{ + unsigned int ptr; + + /* + * In IEC 61883-6, one data block represents one event. In ALSA, one + * event equals to one PCM frame. But Dice has a quirk to transfer + * two PCM frames in one data block. + */ + if (s->double_pcm_frames) + frames *= 2; ptr = s->pcm_buffer_pointer + frames; if (ptr >= pcm->runtime->buffer_size) diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index d8ee7b0e9386..4823c08196ac 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -125,6 +125,7 @@ struct amdtp_stream { unsigned int pcm_buffer_pointer; unsigned int pcm_period_pointer; bool pointer_flush; + bool double_pcm_frames; struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index a9a30c0161f1..e3a04d69c853 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c @@ -567,10 +567,14 @@ static int dice_hw_params(struct snd_pcm_substream *substream, return err; /* - * At rates above 96 kHz, pretend that the stream runs at half the - * actual sample rate with twice the number of channels; two samples - * of a channel are stored consecutively in the packet. Requires - * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. + * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in + * one data block of AMDTP packet. Thus sampling transfer frequency is + * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are + * transferred on AMDTP packets at 96 kHz. Two successive samples of a + * channel are stored consecutively in the packet. This quirk is called + * as 'Dual Wire'. + * For this quirk, blocking mode is required and PCM buffer size should + * be aligned to SYT_INTERVAL. */ channels = params_channels(hw_params); if (rate_index > 4) { @@ -579,18 +583,25 @@ static int dice_hw_params(struct snd_pcm_substream *substream, return err; } - for (i = 0; i < channels; i++) { - dice->stream.pcm_positions[i * 2] = i; - dice->stream.pcm_positions[i * 2 + 1] = i + channels; - } - rate /= 2; channels *= 2; + dice->stream.double_pcm_frames = true; + } else { + dice->stream.double_pcm_frames = false; } mode = rate_index_to_mode(rate_index); amdtp_stream_set_parameters(&dice->stream, rate, channels, dice->rx_midi_ports[mode]); + if (rate_index > 4) { + channels /= 2; + + for (i = 0; i < channels; i++) { + dice->stream.pcm_positions[i] = i * 2; + dice->stream.pcm_positions[i + channels] = i * 2 + 1; + } + } + amdtp_stream_set_pcm_format(&dice->stream, params_format(hw_params)); diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index 62b8869f5a4c..279bc565ac7e 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c @@ -30,7 +30,7 @@ #include "mpu401.h" -typedef struct uart401_devc +struct uart401_devc { int base; int irq; @@ -41,14 +41,13 @@ typedef struct uart401_devc int my_dev; int share_irq; spinlock_t lock; -} -uart401_devc; +}; #define DATAPORT (devc->base) #define COMDPORT (devc->base+1) #define STATPORT (devc->base+1) -static int uart401_status(uart401_devc * devc) +static int uart401_status(struct uart401_devc *devc) { return inb(STATPORT); } @@ -56,17 +55,17 @@ static int uart401_status(uart401_devc * devc) #define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL)) #define output_ready(devc) (!(uart401_status(devc)&OUTPUT_READY)) -static void uart401_cmd(uart401_devc * devc, unsigned char cmd) +static void uart401_cmd(struct uart401_devc *devc, unsigned char cmd) { outb((cmd), COMDPORT); } -static int uart401_read(uart401_devc * devc) +static int uart401_read(struct uart401_devc *devc) { return inb(DATAPORT); } -static void uart401_write(uart401_devc * devc, unsigned char byte) +static void uart401_write(struct uart401_devc *devc, unsigned char byte) { outb((byte), DATAPORT); } @@ -77,10 +76,10 @@ static void uart401_write(uart401_devc * devc, unsigned char byte) #define MPU_RESET 0xFF #define UART_MODE_ON 0x3F -static int reset_uart401(uart401_devc * devc); -static void enter_uart_mode(uart401_devc * devc); +static int reset_uart401(struct uart401_devc *devc); +static void enter_uart_mode(struct uart401_devc *devc); -static void uart401_input_loop(uart401_devc * devc) +static void uart401_input_loop(struct uart401_devc *devc) { int work_limit=30000; @@ -99,7 +98,7 @@ static void uart401_input_loop(uart401_devc * devc) irqreturn_t uart401intr(int irq, void *dev_id) { - uart401_devc *devc = dev_id; + struct uart401_devc *devc = dev_id; if (devc == NULL) { @@ -118,7 +117,8 @@ uart401_open(int dev, int mode, void (*output) (int dev) ) { - uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; + struct uart401_devc *devc = (struct uart401_devc *) + midi_devs[dev]->devc; if (devc->opened) return -EBUSY; @@ -138,7 +138,8 @@ uart401_open(int dev, int mode, static void uart401_close(int dev) { - uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; + struct uart401_devc *devc = (struct uart401_devc *) + midi_devs[dev]->devc; reset_uart401(devc); devc->opened = 0; @@ -148,7 +149,8 @@ static int uart401_out(int dev, unsigned char midi_byte) { int timeout; unsigned long flags; - uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc; + struct uart401_devc *devc = (struct uart401_devc *) + midi_devs[dev]->devc; if (devc->disabled) return 1; @@ -219,7 +221,7 @@ static const struct midi_operations uart401_operations = .buffer_status = uart401_buffer_status, }; -static void enter_uart_mode(uart401_devc * devc) +static void enter_uart_mode(struct uart401_devc *devc) { int ok, timeout; unsigned long flags; @@ -241,7 +243,7 @@ static void enter_uart_mode(uart401_devc * devc) spin_unlock_irqrestore(&devc->lock,flags); } -static int reset_uart401(uart401_devc * devc) +static int reset_uart401(struct uart401_devc *devc) { int ok, timeout, n; @@ -285,7 +287,7 @@ static int reset_uart401(uart401_devc * devc) int probe_uart401(struct address_info *hw_config, struct module *owner) { - uart401_devc *devc; + struct uart401_devc *devc; char *name = "MPU-401 (UART) MIDI"; int ok = 0; unsigned long flags; @@ -300,7 +302,7 @@ int probe_uart401(struct address_info *hw_config, struct module *owner) return 0; } - devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL); + devc = kmalloc(sizeof(struct uart401_devc), GFP_KERNEL); if (!devc) { printk(KERN_WARNING "uart401: Can't allocate memory\n"); goto cleanup_region; @@ -392,7 +394,7 @@ cleanup_region: void unload_uart401(struct address_info *hw_config) { - uart401_devc *devc; + struct uart401_devc *devc; int n=hw_config->slots[4]; /* Not set up */ diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index 672af8b56542..b36ea47527e8 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c @@ -92,7 +92,7 @@ static unsigned short levels[SOUND_MIXER_NRDEVICES] = { 0x0000 /* Monitor */ }; -typedef struct { +struct wavnc_info { struct address_info hw; /* hardware */ char *chip_name; @@ -119,7 +119,7 @@ typedef struct { unsigned int line_mute_state :1;/* set by ioctl or autoselect */ unsigned int use_slider :1;/* use slider setting for o/p vol */ #endif -} wavnc_info; +}; /* * This is the implementation specific mixer information. @@ -129,29 +129,30 @@ struct waveartist_mixer_info { unsigned int recording_devs; /* Recordable devies */ unsigned int stereo_devs; /* Stereo devices */ - unsigned int (*select_input)(wavnc_info *, unsigned int, + unsigned int (*select_input)(struct wavnc_info *, unsigned int, unsigned char *, unsigned char *); - int (*decode_mixer)(wavnc_info *, int, + int (*decode_mixer)(struct wavnc_info *, int, unsigned char, unsigned char); - int (*get_mixer)(wavnc_info *, int); + int (*get_mixer)(struct wavnc_info *, int); }; -typedef struct wavnc_port_info { +struct wavnc_port_info { int open_mode; int speed; int channels; int audio_format; -} wavnc_port_info; +}; static int nr_waveartist_devs; -static wavnc_info adev_info[MAX_AUDIO_DEV]; +static struct wavnc_info adev_info[MAX_AUDIO_DEV]; static DEFINE_SPINLOCK(waveartist_lock); #ifndef CONFIG_ARCH_NETWINDER #define machine_is_netwinder() 0 #else static struct timer_list vnc_timer; -static void vnc_configure_mixer(wavnc_info *devc, unsigned int input_mask); +static void vnc_configure_mixer(struct wavnc_info *devc, + unsigned int input_mask); static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg); static void vnc_slider_tick(unsigned long data); #endif @@ -169,7 +170,7 @@ waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char /* Toggle IRQ acknowledge line */ static inline void -waveartist_iack(wavnc_info *devc) +waveartist_iack(struct wavnc_info *devc) { unsigned int ctlr_port = devc->hw.io_base + CTLR; int old_ctlr; @@ -188,7 +189,7 @@ waveartist_sleep(int timeout_ms) } static int -waveartist_reset(wavnc_info *devc) +waveartist_reset(struct wavnc_info *devc) { struct address_info *hw = &devc->hw; unsigned int timeout, res = -1; @@ -223,7 +224,7 @@ waveartist_reset(wavnc_info *devc) * and can send or receive multiple words. */ static int -waveartist_cmd(wavnc_info *devc, +waveartist_cmd(struct wavnc_info *devc, int nr_cmd, unsigned int *cmd, int nr_resp, unsigned int *resp) { @@ -299,7 +300,7 @@ waveartist_cmd(wavnc_info *devc, * Send one command word */ static inline int -waveartist_cmd1(wavnc_info *devc, unsigned int cmd) +waveartist_cmd1(struct wavnc_info *devc, unsigned int cmd) { return waveartist_cmd(devc, 1, &cmd, 0, NULL); } @@ -308,7 +309,7 @@ waveartist_cmd1(wavnc_info *devc, unsigned int cmd) * Send one command, receive one word */ static inline unsigned int -waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd) +waveartist_cmd1_r(struct wavnc_info *devc, unsigned int cmd) { unsigned int ret; @@ -322,7 +323,7 @@ waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd) * word (and throw it away) */ static inline int -waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg) +waveartist_cmd2(struct wavnc_info *devc, unsigned int cmd, unsigned int arg) { unsigned int vals[2]; @@ -336,7 +337,7 @@ waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg) * Send a triple command */ static inline int -waveartist_cmd3(wavnc_info *devc, unsigned int cmd, +waveartist_cmd3(struct wavnc_info *devc, unsigned int cmd, unsigned int arg1, unsigned int arg2) { unsigned int vals[3]; @@ -349,7 +350,7 @@ waveartist_cmd3(wavnc_info *devc, unsigned int cmd, } static int -waveartist_getrev(wavnc_info *devc, char *rev) +waveartist_getrev(struct wavnc_info *devc, char *rev) { unsigned int temp[2]; unsigned int cmd = WACMD_GETREV; @@ -371,15 +372,15 @@ static void waveartist_trigger(int dev, int state); static int waveartist_open(int dev, int mode) { - wavnc_info *devc; - wavnc_port_info *portc; + struct wavnc_info *devc; + struct wavnc_port_info *portc; unsigned long flags; if (dev < 0 || dev >= num_audiodevs) return -ENXIO; - devc = (wavnc_info *) audio_devs[dev]->devc; - portc = (wavnc_port_info *) audio_devs[dev]->portc; + devc = (struct wavnc_info *) audio_devs[dev]->devc; + portc = (struct wavnc_port_info *) audio_devs[dev]->portc; spin_lock_irqsave(&waveartist_lock, flags); if (portc->open_mode || (devc->open_mode & mode)) { @@ -404,8 +405,10 @@ waveartist_open(int dev, int mode) static void waveartist_close(int dev) { - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; unsigned long flags; spin_lock_irqsave(&waveartist_lock, flags); @@ -422,8 +425,10 @@ waveartist_close(int dev) static void waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; unsigned long flags; unsigned int count = __count; @@ -467,8 +472,10 @@ waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag) static void waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; unsigned long flags; unsigned int count = __count; @@ -514,7 +521,7 @@ waveartist_ioctl(int dev, unsigned int cmd, void __user * arg) } static unsigned int -waveartist_get_speed(wavnc_port_info *portc) +waveartist_get_speed(struct wavnc_port_info *portc) { unsigned int speed; @@ -542,7 +549,7 @@ waveartist_get_speed(wavnc_port_info *portc) } static unsigned int -waveartist_get_bits(wavnc_port_info *portc) +waveartist_get_bits(struct wavnc_port_info *portc) { unsigned int bits; @@ -560,8 +567,10 @@ static int waveartist_prepare_for_input(int dev, int bsize, int bcount) { unsigned long flags; - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; unsigned int speed, bits; if (devc->audio_mode) @@ -615,8 +624,10 @@ static int waveartist_prepare_for_output(int dev, int bsize, int bcount) { unsigned long flags; - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; unsigned int speed, bits; /* @@ -660,8 +671,9 @@ waveartist_prepare_for_output(int dev, int bsize, int bcount) static void waveartist_halt(int dev) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; - wavnc_info *devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; + struct wavnc_info *devc; if (portc->open_mode & OPEN_WRITE) waveartist_halt_output(dev); @@ -669,14 +681,15 @@ waveartist_halt(int dev) if (portc->open_mode & OPEN_READ) waveartist_halt_input(dev); - devc = (wavnc_info *) audio_devs[dev]->devc; + devc = (struct wavnc_info *) audio_devs[dev]->devc; devc->audio_mode = 0; } static void waveartist_halt_input(int dev) { - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; unsigned long flags; spin_lock_irqsave(&waveartist_lock, flags); @@ -703,7 +716,8 @@ waveartist_halt_input(int dev) static void waveartist_halt_output(int dev) { - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; unsigned long flags; spin_lock_irqsave(&waveartist_lock, flags); @@ -727,8 +741,10 @@ waveartist_halt_output(int dev) static void waveartist_trigger(int dev, int state) { - wavnc_info *devc = (wavnc_info *) audio_devs[dev]->devc; - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_info *devc = (struct wavnc_info *) + audio_devs[dev]->devc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; unsigned long flags; if (debug_flg & DEBUG_TRIGGER) { @@ -764,7 +780,8 @@ waveartist_trigger(int dev, int state) static int waveartist_set_speed(int dev, int arg) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; if (arg <= 0) return portc->speed; @@ -782,7 +799,8 @@ waveartist_set_speed(int dev, int arg) static short waveartist_set_channels(int dev, short arg) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; if (arg != 1 && arg != 2) return portc->channels; @@ -794,7 +812,8 @@ waveartist_set_channels(int dev, short arg) static unsigned int waveartist_set_bits(int dev, unsigned int arg) { - wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc; + struct wavnc_port_info *portc = (struct wavnc_port_info *) + audio_devs[dev]->portc; if (arg == 0) return portc->audio_format; @@ -829,7 +848,7 @@ static struct audio_driver waveartist_audio_driver = { static irqreturn_t waveartist_intr(int irq, void *dev_id) { - wavnc_info *devc = dev_id; + struct wavnc_info *devc = dev_id; int irqstatus, status; spin_lock(&waveartist_lock); @@ -912,7 +931,7 @@ static const struct mix_ent mix_devs[SOUND_MIXER_NRDEVICES] = { }; static void -waveartist_mixer_update(wavnc_info *devc, int whichDev) +waveartist_mixer_update(struct wavnc_info *devc, int whichDev) { unsigned int lev_left, lev_right; @@ -973,7 +992,8 @@ waveartist_mixer_update(wavnc_info *devc, int whichDev) * relevant *_select_input function has done that for us. */ static void -waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev) +waveartist_set_adc_mux(struct wavnc_info *devc, char left_dev, + char right_dev) { unsigned int reg_08, reg_09; @@ -996,7 +1016,7 @@ waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev) * SOUND_MASK_MIC Mic Microphone */ static unsigned int -waveartist_select_input(wavnc_info *devc, unsigned int recmask, +waveartist_select_input(struct wavnc_info *devc, unsigned int recmask, unsigned char *dev_l, unsigned char *dev_r) { unsigned int recdev = ADC_MUX_NONE; @@ -1024,7 +1044,8 @@ waveartist_select_input(wavnc_info *devc, unsigned int recmask, } static int -waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, +waveartist_decode_mixer(struct wavnc_info *devc, int dev, + unsigned char lev_l, unsigned char lev_r) { switch (dev) { @@ -1050,7 +1071,7 @@ waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, return dev; } -static int waveartist_get_mixer(wavnc_info *devc, int dev) +static int waveartist_get_mixer(struct wavnc_info *devc, int dev) { return devc->levels[dev]; } @@ -1068,7 +1089,7 @@ static const struct waveartist_mixer_info waveartist_mixer = { }; static void -waveartist_set_recmask(wavnc_info *devc, unsigned int recmask) +waveartist_set_recmask(struct wavnc_info *devc, unsigned int recmask) { unsigned char dev_l, dev_r; @@ -1092,7 +1113,7 @@ waveartist_set_recmask(wavnc_info *devc, unsigned int recmask) } static int -waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level) +waveartist_set_mixer(struct wavnc_info *devc, int dev, unsigned int level) { unsigned int lev_left = level & 0x00ff; unsigned int lev_right = (level & 0xff00) >> 8; @@ -1120,7 +1141,7 @@ waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level) static int waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg) { - wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc; + struct wavnc_info *devc = (struct wavnc_info *)audio_devs[dev]->devc; int ret = 0, val, nr; /* @@ -1204,7 +1225,7 @@ static struct mixer_operations waveartist_mixer_operations = }; static void -waveartist_mixer_reset(wavnc_info *devc) +waveartist_mixer_reset(struct wavnc_info *devc) { int i; @@ -1241,9 +1262,9 @@ waveartist_mixer_reset(wavnc_info *devc) waveartist_mixer_update(devc, i); } -static int __init waveartist_init(wavnc_info *devc) +static int __init waveartist_init(struct wavnc_info *devc) { - wavnc_port_info *portc; + struct wavnc_port_info *portc; char rev[3], dev_name[64]; int my_dev; @@ -1261,7 +1282,7 @@ static int __init waveartist_init(wavnc_info *devc) conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq, devc->hw.dma, devc->hw.dma2); - portc = kzalloc(sizeof(wavnc_port_info), GFP_KERNEL); + portc = kzalloc(sizeof(struct wavnc_port_info), GFP_KERNEL); if (portc == NULL) goto nomem; @@ -1330,7 +1351,7 @@ nomem: static int __init probe_waveartist(struct address_info *hw_config) { - wavnc_info *devc = &adev_info[nr_waveartist_devs]; + struct wavnc_info *devc = &adev_info[nr_waveartist_devs]; if (nr_waveartist_devs >= MAX_AUDIO_DEV) { printk(KERN_WARNING "waveartist: too many audio devices\n"); @@ -1367,7 +1388,7 @@ static int __init probe_waveartist(struct address_info *hw_config) static void __init attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix) { - wavnc_info *devc = &adev_info[nr_waveartist_devs]; + struct wavnc_info *devc = &adev_info[nr_waveartist_devs]; /* * NOTE! If irq < 0, there is another driver which has allocated the @@ -1410,7 +1431,7 @@ attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *m static void __exit unload_waveartist(struct address_info *hw) { - wavnc_info *devc = NULL; + struct wavnc_info *devc = NULL; int i; for (i = 0; i < nr_waveartist_devs; i++) @@ -1478,7 +1499,7 @@ static void __exit unload_waveartist(struct address_info *hw) #define VNC_DISABLE_AUTOSWITCH 0x80 static inline void -vnc_mute_spkr(wavnc_info *devc) +vnc_mute_spkr(struct wavnc_info *devc) { unsigned long flags; @@ -1488,7 +1509,7 @@ vnc_mute_spkr(wavnc_info *devc) } static void -vnc_mute_lout(wavnc_info *devc) +vnc_mute_lout(struct wavnc_info *devc) { unsigned int left, right; @@ -1507,7 +1528,7 @@ vnc_mute_lout(wavnc_info *devc) } static int -vnc_volume_slider(wavnc_info *devc) +vnc_volume_slider(struct wavnc_info *devc) { static signed int old_slider_volume; unsigned long flags; @@ -1567,7 +1588,7 @@ vnc_volume_slider(wavnc_info *devc) * SOUND_MASK_MIC Right Mic Builtin microphone */ static unsigned int -netwinder_select_input(wavnc_info *devc, unsigned int recmask, +netwinder_select_input(struct wavnc_info *devc, unsigned int recmask, unsigned char *dev_l, unsigned char *dev_r) { unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE; @@ -1604,7 +1625,7 @@ netwinder_select_input(wavnc_info *devc, unsigned int recmask, } static int -netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, +netwinder_decode_mixer(struct wavnc_info *devc, int dev, unsigned char lev_l, unsigned char lev_r) { switch (dev) { @@ -1643,7 +1664,7 @@ netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l, return dev; } -static int netwinder_get_mixer(wavnc_info *devc, int dev) +static int netwinder_get_mixer(struct wavnc_info *devc, int dev) { int levels; @@ -1703,7 +1724,7 @@ static const struct waveartist_mixer_info netwinder_mixer = { }; static void -vnc_configure_mixer(wavnc_info *devc, unsigned int recmask) +vnc_configure_mixer(struct wavnc_info *devc, unsigned int recmask) { if (!devc->no_autoselect) { if (devc->handset_detect) { @@ -1729,7 +1750,7 @@ vnc_configure_mixer(wavnc_info *devc, unsigned int recmask) } static int -vnc_slider(wavnc_info *devc) +vnc_slider(struct wavnc_info *devc) { signed int slider_volume; unsigned int temp, old_hs, old_td; @@ -1795,7 +1816,7 @@ vnc_slider_tick(unsigned long data) static int vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg) { - wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc; + struct wavnc_info *devc = (struct wavnc_info *)audio_devs[dev]->devc; int val; switch (cmd) { diff --git a/sound/pci/ctxfi/ct20k1reg.h b/sound/pci/ctxfi/ct20k1reg.h index f2e34e3f27ee..5851249f11d9 100644 --- a/sound/pci/ctxfi/ct20k1reg.h +++ b/sound/pci/ctxfi/ct20k1reg.h @@ -7,7 +7,7 @@ */ #ifndef CT20K1REG_H -#define CT20k1REG_H +#define CT20K1REG_H /* 20k1 registers */ #define DSPXRAM_START 0x000000 @@ -632,5 +632,3 @@ #define I2SD_R 0x19L #endif /* CT20K1REG_H */ - - diff --git a/sound/pci/hda/ca0132_regs.h b/sound/pci/hda/ca0132_regs.h index 07e760937d3c..8371274aa811 100644 --- a/sound/pci/hda/ca0132_regs.h +++ b/sound/pci/hda/ca0132_regs.h @@ -20,7 +20,7 @@ */ #ifndef __CA0132_REGS_H -#define __CA0312_REGS_H +#define __CA0132_REGS_H #define DSP_CHIP_OFFSET 0x100000 #define DSP_DBGCNTL_MODULE_OFFSET 0xE30 diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5db1948699d8..aa302fb03fc5 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -265,6 +265,7 @@ enum { AZX_DRIVER_TERA, AZX_DRIVER_CTX, AZX_DRIVER_CTHDA, + AZX_DRIVER_CMEDIA, AZX_DRIVER_GENERIC, AZX_NUM_DRIVERS, /* keep this as last entry */ }; @@ -330,6 +331,7 @@ static char *driver_short_names[] = { [AZX_DRIVER_TERA] = "HDA Teradici", [AZX_DRIVER_CTX] = "HDA Creative", [AZX_DRIVER_CTHDA] = "HDA Creative", + [AZX_DRIVER_CMEDIA] = "HDA C-Media", [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; @@ -1373,6 +1375,7 @@ static void azx_check_snoop_available(struct azx *chip) snoop = false; break; case AZX_DRIVER_CTHDA: + case AZX_DRIVER_CMEDIA: snoop = false; break; } @@ -2154,6 +2157,10 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB }, #endif + /* CM8888 */ + { PCI_DEVICE(0x13f6, 0x5011), + .driver_data = AZX_DRIVER_CMEDIA | + AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB }, /* Vortex86MX */ { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, /* VMware HDAudio */ diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 4f3aba78f720..5d8455e2dacd 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4376,6 +4376,9 @@ static void ca0132_download_dsp(struct hda_codec *codec) return; /* NOP */ #endif + if (spec->dsp_state == DSP_DOWNLOAD_FAILED) + return; /* don't retry failures */ + chipio_enable_clocks(codec); spec->dsp_state = DSP_DOWNLOADING; if (!ca0132_download_dsp_images(codec)) @@ -4552,7 +4555,8 @@ static int ca0132_init(struct hda_codec *codec) struct auto_pin_cfg *cfg = &spec->autocfg; int i; - spec->dsp_state = DSP_DOWNLOAD_INIT; + if (spec->dsp_state != DSP_DOWNLOAD_FAILED) + spec->dsp_state = DSP_DOWNLOAD_INIT; spec->curr_chip_addx = INVALID_CHIP_ADDRESS; snd_hda_power_up(codec); @@ -4663,6 +4667,7 @@ static int patch_ca0132(struct hda_codec *codec) codec->spec = spec; spec->codec = codec; + spec->dsp_state = DSP_DOWNLOAD_INIT; spec->num_mixers = 1; spec->mixers[0] = ca0132_mixer; diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index ed3d133ffbb6..c895a8f21192 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -75,15 +75,62 @@ static int patch_cmi9880(struct hda_codec *codec) return err; } +static int patch_cmi8888(struct hda_codec *codec) +{ + struct cmi_spec *spec; + struct auto_pin_cfg *cfg; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + + codec->spec = spec; + cfg = &spec->gen.autocfg; + snd_hda_gen_spec_init(&spec->gen); + + /* mask NID 0x10 from the playback volume selection; + * it's a headphone boost volume handled manually below + */ + spec->gen.out_vol_mask = (1ULL << 0x10); + + err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); + if (err < 0) + goto error; + err = snd_hda_gen_parse_auto_config(codec, cfg); + if (err < 0) + goto error; + + if (get_defcfg_device(snd_hda_codec_get_pincfg(codec, 0x10)) == + AC_JACK_HP_OUT) { + static const struct snd_kcontrol_new amp_kctl = + HDA_CODEC_VOLUME("Headphone Amp Playback Volume", + 0x10, 0, HDA_OUTPUT); + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &_kctl)) { + err = -ENOMEM; + goto error; + } + } + + codec->patch_ops = cmi_auto_patch_ops; + return 0; + + error: + snd_hda_gen_free(codec); + return err; +} + /* * patch entries */ static const struct hda_codec_preset snd_hda_preset_cmedia[] = { + { .id = 0x13f68888, .name = "CMI8888", .patch = patch_cmi8888 }, { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, {} /* terminator */ }; +MODULE_ALIAS("snd-hda-codec-id:13f68888"); MODULE_ALIAS("snd-hda-codec-id:13f69880"); MODULE_ALIAS("snd-hda-codec-id:434d4980"); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 7627a69ca6d7..47ccb8f44adb 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -26,6 +26,7 @@ #include <linux/module.h> #include <sound/core.h> #include <sound/jack.h> +#include <sound/tlv.h> #include "hda_codec.h" #include "hda_local.h" @@ -216,6 +217,7 @@ enum { CXT_FIXUP_HEADPHONE_MIC_PIN, CXT_FIXUP_HEADPHONE_MIC, CXT_FIXUP_GPIO1, + CXT_FIXUP_ASPIRE_DMIC, CXT_FIXUP_THINKPAD_ACPI, CXT_FIXUP_OLPC_XO, CXT_FIXUP_CAP_MIX_AMP, @@ -663,6 +665,12 @@ static const struct hda_fixup cxt_fixups[] = { { } }, }, + [CXT_FIXUP_ASPIRE_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_stereo_dmic, + .chained = true, + .chain_id = CXT_FIXUP_GPIO1, + }, [CXT_FIXUP_THINKPAD_ACPI] = { .type = HDA_FIXUP_FUNC, .v.func = hda_fixup_thinkpad_acpi, @@ -743,7 +751,7 @@ static const struct hda_model_fixup cxt5051_fixup_models[] = { static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1), + SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), @@ -769,6 +777,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = { { .id = CXT_PINCFG_LENOVO_TP410, .name = "tp410" }, { .id = CXT_FIXUP_THINKPAD_ACPI, .name = "thinkpad" }, { .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" }, + { .id = CXT_PINCFG_LEMOTE_A1205, .name = "lemote-a1205" }, { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, {} }; @@ -859,6 +868,11 @@ static int patch_conexant_auto(struct hda_codec *codec) if (err < 0) goto error; + if (codec->vendor_id == 0x14f15051) { + /* minimum value is actually mute */ + spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; + } + codec->patch_ops = cx_auto_patch_ops; /* Some laptops with Conexant chips show stalls in S3 resume, diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 36badba2dcec..99d7d7fecaad 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -50,6 +50,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec)) #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882) +#define is_cherryview(codec) ((codec)->vendor_id == 0x80862883) +#define is_valleyview_plus(codec) (is_valleyview(codec) || is_cherryview(codec)) struct hdmi_spec_per_cvt { hda_nid_t cvt_nid; @@ -1459,7 +1461,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, mux_idx); /* configure unused pins to choose other converters */ - if (is_haswell_plus(codec) || is_valleyview(codec)) + if (is_haswell_plus(codec) || is_valleyview_plus(codec)) intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); @@ -1598,7 +1600,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) * and this can make HW reset converter selection on a pin. */ if (eld->eld_valid && !old_eld_valid && per_pin->setup) { - if (is_haswell_plus(codec) || is_valleyview(codec)) { + if (is_haswell_plus(codec) || + is_valleyview_plus(codec)) { intel_verify_pin_cvt_connect(codec, per_pin); intel_not_share_assigned_cvt(codec, pin_nid, per_pin->mux_idx); @@ -1779,7 +1782,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, bool non_pcm; int pinctl; - if (is_haswell_plus(codec) || is_valleyview(codec)) { + if (is_haswell_plus(codec) || is_valleyview_plus(codec)) { /* Verify pin:cvt selections to avoid silent audio after S3. * After S3, the audio driver restores pin:cvt selections * but this can happen before gfx is ready and such selection @@ -2330,9 +2333,8 @@ static int patch_generic_hdmi(struct hda_codec *codec) intel_haswell_fixup_enable_dp12(codec); } - if (is_haswell(codec) || is_valleyview(codec)) { + if (is_haswell_plus(codec) || is_valleyview_plus(codec)) codec->depop_delay = 0; - } if (hdmi_parse_codec(codec) < 0) { codec->spec = NULL; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 654c8f16d150..1ba22fb527c2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -181,6 +181,8 @@ static void alc_fix_pll(struct hda_codec *codec) spec->pll_coef_idx); val = snd_hda_codec_read(codec, spec->pll_nid, 0, AC_VERB_GET_PROC_COEF, 0); + if (val == -1) + return; snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, spec->pll_coef_idx); snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, @@ -326,6 +328,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0885: case 0x10ec0887: /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ + case 0x10ec0900: alc889_coef_init(codec); break; case 0x10ec0888: @@ -2348,6 +2351,7 @@ static int patch_alc882(struct hda_codec *codec) switch (codec->vendor_id) { case 0x10ec0882: case 0x10ec0885: + case 0x10ec0900: break; default: /* ALC883 and variants */ @@ -2782,9 +2786,32 @@ static int alc269_parse_auto_config(struct hda_codec *codec) return alc_parse_auto_config(codec, alc269_ignore, ssids); } +static int find_ext_mic_pin(struct hda_codec *codec); + +static void alc286_shutup(struct hda_codec *codec) +{ + int i; + int mic_pin = find_ext_mic_pin(codec); + /* don't shut up pins when unloading the driver; otherwise it breaks + * the default pin setup at the next load of the driver + */ + if (codec->bus->shutdown) + return; + for (i = 0; i < codec->init_pins.used; i++) { + struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); + /* use read here for syncing after issuing each verb */ + if (pin->nid != mic_pin) + snd_hda_codec_read(codec, pin->nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } + codec->pins_shutup = 1; +} + static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); + if (val == -1) + return; if (power_up) val |= 1 << 11; else @@ -3243,6 +3270,15 @@ static int alc269_resume(struct hda_codec *codec) snd_hda_codec_resume_cache(codec); alc_inv_dmic_sync(codec, true); hda_call_check_power_status(codec, 0x01); + + /* on some machine, the BIOS will clear the codec gpio data when enter + * suspend, and won't restore the data after resume, so we restore it + * in the driver. + */ + if (spec->gpio_led) + snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_led); + if (spec->has_alc5505_dsp) alc5505_dsp_resume(codec); @@ -4072,7 +4108,7 @@ static unsigned int alc_power_filter_xps13(struct hda_codec *codec, /* Avoid pop noises when headphones are plugged in */ if (spec->gen.hp_jack_present) - if (nid == codec->afg || nid == 0x02) + if (nid == codec->afg || nid == 0x02 || nid == 0x15) return AC_PWRST_D0; return power_state; } @@ -4082,8 +4118,19 @@ static void alc_fixup_dell_xps13(struct hda_codec *codec, { if (action == HDA_FIXUP_ACT_PROBE) { struct alc_spec *spec = codec->spec; + struct hda_input_mux *imux = &spec->gen.input_mux; + int i; + spec->shutup = alc_no_shutup; codec->power_filter = alc_power_filter_xps13; + + /* Make the internal mic the default input source. */ + for (i = 0; i < imux->num_items; i++) { + if (spec->gen.imux_pins[i] == 0x12) { + spec->gen.cur_mux[0] = i; + break; + } + } } } @@ -4363,6 +4410,7 @@ enum { ALC292_FIXUP_TPT440_DOCK, ALC283_FIXUP_BXBT2807_MIC, ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, + ALC282_FIXUP_ASPIRE_V5_PINS, }; static const struct hda_fixup alc269_fixups[] = { @@ -4810,6 +4858,22 @@ static const struct hda_fixup alc269_fixups[] = { .chained_before = true, .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE }, + [ALC282_FIXUP_ASPIRE_V5_PINS] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x12, 0x90a60130 }, + { 0x14, 0x90170110 }, + { 0x17, 0x40000008 }, + { 0x18, 0x411111f0 }, + { 0x19, 0x411111f0 }, + { 0x1a, 0x411111f0 }, + { 0x1b, 0x411111f0 }, + { 0x1d, 0x40f89b2d }, + { 0x1e, 0x411111f0 }, + { 0x21, 0x0321101f }, + { }, + }, + }, }; @@ -4821,6 +4885,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), + SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), @@ -5279,27 +5344,30 @@ static void alc269_fill_coef(struct hda_codec *codec) if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { val = alc_read_coef_idx(codec, 0x04); /* Power up output pin */ - alc_write_coef_idx(codec, 0x04, val | (1<<11)); + if (val != -1) + alc_write_coef_idx(codec, 0x04, val | (1<<11)); } if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { val = alc_read_coef_idx(codec, 0xd); - if ((val & 0x0c00) >> 10 != 0x1) { + if (val != -1 && (val & 0x0c00) >> 10 != 0x1) { /* Capless ramp up clock control */ alc_write_coef_idx(codec, 0xd, val | (1<<10)); } val = alc_read_coef_idx(codec, 0x17); - if ((val & 0x01c0) >> 6 != 0x4) { + if (val != -1 && (val & 0x01c0) >> 6 != 0x4) { /* Class D power on reset */ alc_write_coef_idx(codec, 0x17, val | (1<<7)); } } val = alc_read_coef_idx(codec, 0xd); /* Class D */ - alc_write_coef_idx(codec, 0xd, val | (1<<14)); + if (val != -1) + alc_write_coef_idx(codec, 0xd, val | (1<<14)); val = alc_read_coef_idx(codec, 0x4); /* HP */ - alc_write_coef_idx(codec, 0x4, val | (1<<11)); + if (val != -1) + alc_write_coef_idx(codec, 0x4, val | (1<<11)); } /* @@ -5384,6 +5452,7 @@ static int patch_alc269(struct hda_codec *codec) case 0x10ec0286: case 0x10ec0288: spec->codec_variant = ALC269_TYPE_ALC286; + spec->shutup = alc286_shutup; break; case 0x10ec0255: spec->codec_variant = ALC269_TYPE_ALC255; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ea823e1100da..98cd1908c039 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -566,8 +566,8 @@ static void stac_init_power_map(struct hda_codec *codec) if (snd_hda_jack_tbl_get(codec, nid)) continue; if (def_conf == AC_JACK_PORT_COMPLEX && - !(spec->vref_mute_led_nid == nid || - is_jack_detectable(codec, nid))) { + spec->vref_mute_led_nid != nid && + is_jack_detectable(codec, nid)) { snd_hda_jack_detect_enable_callback(codec, nid, STAC_PWR_EVENT, jack_update_power); @@ -4276,11 +4276,18 @@ static int stac_parse_auto_config(struct hda_codec *codec) return err; } - stac_init_power_map(codec); - return 0; } +static int stac_build_controls(struct hda_codec *codec) +{ + int err = snd_hda_gen_build_controls(codec); + + if (err < 0) + return err; + stac_init_power_map(codec); + return 0; +} static int stac_init(struct hda_codec *codec) { @@ -4392,7 +4399,7 @@ static int stac_suspend(struct hda_codec *codec) #endif /* CONFIG_PM */ static const struct hda_codec_ops stac_patch_ops = { - .build_controls = snd_hda_gen_build_controls, + .build_controls = stac_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = stac_init, .free = stac_free, diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index bd41ee4da078..2c71f16bd661 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1278,6 +1278,8 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, else rates = &arizona_48k_bclk_rates[0]; + wl = snd_pcm_format_width(params_format(params)); + if (tdm_slots) { arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n", tdm_slots, tdm_width); @@ -1285,6 +1287,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, channels = tdm_slots; } else { bclk_target = snd_soc_params_to_bclk(params); + tdm_width = wl; } if (chan_limit && chan_limit < channels) { @@ -1319,8 +1322,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", rates[bclk], rates[bclk] / lrclk); - wl = snd_pcm_format_width(params_format(params)); - frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; + frame = wl << ARIZONA_AIF1TX_WL_SHIFT | tdm_width; reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame); diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index a20b30ca52c0..69a85164357c 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -282,10 +282,10 @@ static const struct cs4265_clk_para clk_map_table[] = { /*64k*/ {8192000, 64000, 1, 0}, - {1228800, 64000, 1, 1}, - {1693440, 64000, 1, 2}, - {2457600, 64000, 1, 3}, - {3276800, 64000, 1, 4}, + {12288000, 64000, 1, 1}, + {16934400, 64000, 1, 2}, + {24576000, 64000, 1, 3}, + {32768000, 64000, 1, 4}, /* 88.2k */ {11289600, 88200, 1, 0}, @@ -435,10 +435,10 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params)); if (index >= 0) { snd_soc_update_bits(codec, CS4265_ADC_CTL, - CS4265_ADC_FM, clk_map_table[index].fm_mode); + CS4265_ADC_FM, clk_map_table[index].fm_mode << 6); snd_soc_update_bits(codec, CS4265_MCLK_FREQ, CS4265_MCLK_FREQ_MASK, - clk_map_table[index].mclkdiv); + clk_map_table[index].mclkdiv << 4); } else { dev_err(codec->dev, "can't get correct mclk\n"); @@ -458,12 +458,12 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, if (params_width(params) == 16) { snd_soc_update_bits(codec, CS4265_DAC_CTL, CS4265_DAC_CTL_DIF, (1 << 5)); - snd_soc_update_bits(codec, CS4265_ADC_CTL, + snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, CS4265_SPDIF_CTL2_DIF, (1 << 7)); } else { snd_soc_update_bits(codec, CS4265_DAC_CTL, CS4265_DAC_CTL_DIF, (3 << 5)); - snd_soc_update_bits(codec, CS4265_ADC_CTL, + snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, CS4265_SPDIF_CTL2_DIF, (1 << 7)); } break; @@ -472,7 +472,7 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, CS4265_DAC_CTL_DIF, 0); snd_soc_update_bits(codec, CS4265_ADC_CTL, CS4265_ADC_DIF, 0); - snd_soc_update_bits(codec, CS4265_ADC_CTL, + snd_soc_update_bits(codec, CS4265_SPDIF_CTL2, CS4265_SPDIF_CTL2_DIF, (1 << 6)); break; diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h index 1dceafeec415..f586cbd30b77 100644 --- a/sound/soc/codecs/da732x.h +++ b/sound/soc/codecs/da732x.h @@ -11,7 +11,7 @@ */ #ifndef __DA732X_H_ -#define __DA732X_H +#define __DA732X_H_ #include <sound/soc.h> diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 163ec3855fd4..0c8aefab404c 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -259,13 +259,13 @@ static const struct soc_enum pcm512x_veds = pcm512x_ramp_step_text); static const struct snd_kcontrol_new pcm512x_controls[] = { -SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2, +SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), -SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, +SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, PCM512x_RQMR_SHIFT, 1, 1), SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 6bc6efdec550..f1ec6e6bd08a 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2059,6 +2059,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { static const struct regmap_config rt5640_regmap = { .reg_bits = 8, .val_bits = 16, + .use_single_rw = true, .max_register = RT5640_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5640_ranges) * RT5640_PR_SPACING), diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 67f14556462f..5337c448b5e3 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -2135,10 +2135,10 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "BST2", NULL, "IN2P" }, { "BST2", NULL, "IN2N" }, - { "IN1P", NULL, "micbias1" }, - { "IN1N", NULL, "micbias1" }, - { "IN2P", NULL, "micbias1" }, - { "IN2N", NULL, "micbias1" }, + { "IN1P", NULL, "MICBIAS1" }, + { "IN1N", NULL, "MICBIAS1" }, + { "IN2P", NULL, "MICBIAS1" }, + { "IN2N", NULL, "MICBIAS1" }, { "ADC 1", NULL, "BST1" }, { "ADC 1", NULL, "ADC 1 power" }, diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index 9aa1323fb2ab..89c748dd3d6e 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -4,7 +4,7 @@ * sound/soc/codecs/sta529.c -- spear ALSA Soc codec driver * * Copyright (C) 2012 ST Microelectronics - * Rajeev Kumar <rajeev-dlh.kumar@st.com> + * Rajeev Kumar <rajeevkumar.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -426,5 +426,5 @@ static struct i2c_driver sta529_i2c_driver = { module_i2c_driver(sta529_i2c_driver); MODULE_DESCRIPTION("ASoC STA529 codec driver"); -MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); +MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 0f64c7890eed..aea9e1ff9126 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -189,46 +189,57 @@ static const struct aic31xx_rate_divs aic31xx_divs[] = { /* mclk rate pll: p j d dosr ndac mdac aors nadc madc */ /* 8k rate */ {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2}, + {12000000, 8000, 1, 8, 1920, 128, 32, 3, 128, 32, 3}, {24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2}, {25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2}, /* 11.025k rate */ {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2}, + {12000000, 11025, 1, 8, 4672, 128, 24, 3, 128, 24, 3}, {24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2}, {25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2}, /* 16k rate */ {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2}, + {12000000, 16000, 1, 8, 1920, 128, 16, 3, 128, 16, 3}, {24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2}, {25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2}, /* 22.05k rate */ {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2}, + {12000000, 22050, 1, 8, 4672, 128, 12, 3, 128, 12, 3}, {24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2}, {25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2}, /* 32k rate */ {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2}, + {12000000, 32000, 1, 8, 1920, 128, 8, 3, 128, 8, 3}, {24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2}, {25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2}, /* 44.1k rate */ {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2}, + {12000000, 44100, 1, 8, 4672, 128, 6, 3, 128, 6, 3}, {24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2}, {25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2}, /* 48k rate */ {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2}, + {12000000, 48000, 1, 7, 6800, 96, 5, 4, 96, 5, 4}, {24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2}, {25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2}, /* 88.2k rate */ {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2}, + {12000000, 88200, 1, 8, 4672, 64, 6, 3, 64, 6, 3}, {24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2}, {25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2}, /* 96k rate */ {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2}, + {12000000, 96000, 1, 7, 6800, 48, 5, 4, 48, 5, 4}, {24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2}, {25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2}, /* 176.4k rate */ {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2}, + {12000000, 176400, 1, 8, 4672, 32, 6, 3, 32, 6, 3}, {24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2}, {25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2}, /* 192k rate */ {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2}, + {12000000, 192000, 1, 7, 6800, 24, 5, 4, 24, 5, 4}, {24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2}, {25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2}, }; @@ -680,7 +691,9 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, struct snd_pcm_hw_params *params) { struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); + int bclk_score = snd_soc_params_to_frame_size(params); int bclk_n = 0; + int match = -1; int i; /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ @@ -691,15 +704,37 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) { if (aic31xx_divs[i].rate == params_rate(params) && - aic31xx_divs[i].mclk == aic31xx->sysclk) - break; + aic31xx_divs[i].mclk == aic31xx->sysclk) { + int s = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) % + snd_soc_params_to_frame_size(params); + int bn = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) / + snd_soc_params_to_frame_size(params); + if (s < bclk_score && bn > 0) { + match = i; + bclk_n = bn; + bclk_score = s; + } + } } - if (i == ARRAY_SIZE(aic31xx_divs)) { - dev_err(codec->dev, "%s: Sampling rate %u not supported\n", + if (match == -1) { + dev_err(codec->dev, + "%s: Sample rate (%u) and format not supported\n", __func__, params_rate(params)); + /* See bellow for details how fix this. */ return -EINVAL; } + if (bclk_score != 0) { + dev_warn(codec->dev, "Can not produce exact bitclock"); + /* This is fine if using dsp format, but if using i2s + there may be trouble. To fix the issue edit the + aic31xx_divs table for your mclk and sample + rate. Details can be found from: + http://www.ti.com/lit/ds/symlink/tlv320aic3100.pdf + Section: 5.6 CLOCK Generation and PLL + */ + } + i = match; /* PLL configuration */ snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK, @@ -729,14 +764,6 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr); /* Bit clock divider configuration. */ - bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) - / snd_soc_params_to_frame_size(params); - if (bclk_n == 0) { - dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n", - __func__); - return -EINVAL; - } - snd_soc_update_bits(codec, AIC31XX_BCLKN, AIC31XX_PLL_MASK, bclk_n); diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index c28508da34cf..68347b55f6e1 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -403,7 +403,8 @@ out: return ret; } -static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) +static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, + int div, bool explicit) { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); @@ -420,7 +421,8 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div ACLKXDIV(div - 1), ACLKXDIV_MASK); mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRDIV(div - 1), ACLKRDIV_MASK); - mcasp->bclk_div = div; + if (explicit) + mcasp->bclk_div = div; break; case 2: /* BCLK/LRCLK ratio */ @@ -434,6 +436,12 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div return 0; } +static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, + int div) +{ + return __davinci_mcasp_set_clkdiv(dai, div_id, div, 1); +} + static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { @@ -459,8 +467,17 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, { u32 fmt; u32 tx_rotate = (word_length / 4) & 0x7; - u32 rx_rotate = (32 - word_length) / 4; u32 mask = (1ULL << word_length) - 1; + /* + * For captured data we should not rotate, inversion and masking is + * enoguh to get the data to the right position: + * Format data from bus after reverse (XRBUF) + * S16_LE: |LSB|MSB|xxx|xxx| |xxx|xxx|MSB|LSB| + * S24_3LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB| + * S24_LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB| + * S32_LE: |LSB|DAT|DAT|MSB| |MSB|DAT|DAT|LSB| + */ + u32 rx_rotate = 0; /* * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv() @@ -738,7 +755,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, "Inaccurate BCLK: %u Hz / %u != %u Hz\n", mcasp->sysclk_freq, div, bclk_freq); } - davinci_mcasp_set_clkdiv(cpu_dai, 1, div); + __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0); } ret = mcasp_common_hw_param(mcasp, substream->stream, diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 25c31f1655f6..e961388e6e9c 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -4,7 +4,7 @@ * sound/soc/dwc/designware_i2s.c * * Copyright (C) 2010 ST Microelectronics - * Rajeev Kumar <rajeev-dlh.kumar@st.com> + * Rajeev Kumar <rajeevkumar.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -455,7 +455,7 @@ static struct platform_driver dw_i2s_driver = { module_platform_driver(dw_i2s_driver); -MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); +MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>"); MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:designware_i2s"); diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index f54a8fc99291..f3012b645b51 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -49,7 +49,6 @@ config SND_SOC_FSL_ESAI tristate "Enhanced Serial Audio Interface (ESAI) module support" select REGMAP_MMIO select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n - select SND_SOC_FSL_UTILS help Say Y if you want to add Enhanced Synchronous Audio Interface (ESAI) support for the Freescale CPUs. diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 72d154e7dd03..a3b29ed84963 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -18,7 +18,6 @@ #include "fsl_esai.h" #include "imx-pcm.h" -#include "fsl_utils.h" #define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ @@ -607,7 +606,6 @@ static struct snd_soc_dai_ops fsl_esai_dai_ops = { .hw_params = fsl_esai_hw_params, .set_sysclk = fsl_esai_set_dai_sysclk, .set_fmt = fsl_esai_set_dai_fmt, - .xlate_tdm_slot_mask = fsl_asoc_xlate_tdm_slot_mask, .set_tdm_slot = fsl_esai_set_dai_tdm_slot, }; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 159e517fa09a..cef7776b712c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -481,12 +481,19 @@ static int asoc_simple_card_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&priv->snd_card, priv); ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); + if (ret >= 0) + return ret; err: asoc_simple_card_unref(pdev); return ret; } +static int asoc_simple_card_remove(struct platform_device *pdev) +{ + return asoc_simple_card_unref(pdev); +} + static const struct of_device_id asoc_simple_of_match[] = { { .compatible = "simple-audio-card", }, {}, @@ -500,6 +507,7 @@ static struct platform_driver asoc_simple_card = { .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, + .remove = asoc_simple_card_remove, }; module_platform_driver(asoc_simple_card); diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c index 42edc6f4fc4a..03d0a166b635 100644 --- a/sound/soc/intel/sst-acpi.c +++ b/sound/soc/intel/sst-acpi.c @@ -246,8 +246,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = { }; static struct sst_acpi_mach baytrail_machines[] = { - { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-i2s_master" }, - { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-i2s_master" }, + { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, + { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, {} }; diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/sst-baytrail-ipc.c index 67673a2c0f41..b4ad98c43e5c 100644 --- a/sound/soc/intel/sst-baytrail-ipc.c +++ b/sound/soc/intel/sst-baytrail-ipc.c @@ -817,7 +817,7 @@ static struct sst_dsp_device byt_dev = { .ops = &sst_byt_ops, }; -int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) +int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata) { struct sst_byt *byt = pdata->dsp; @@ -826,14 +826,6 @@ int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) sst_byt_drop_all(byt); dev_dbg(byt->dev, "dsp in reset\n"); - return 0; -} -EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_noirq); - -int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata) -{ - struct sst_byt *byt = pdata->dsp; - dev_dbg(byt->dev, "free all blocks and unload fw\n"); sst_fw_unload(byt->fw); diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/sst-baytrail-ipc.h index 06a4d202689b..8faff6dcf25d 100644 --- a/sound/soc/intel/sst-baytrail-ipc.h +++ b/sound/soc/intel/sst-baytrail-ipc.h @@ -66,7 +66,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt, int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); -int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata); int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata); diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index 599401c0c655..eab1c7d85187 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c @@ -59,6 +59,9 @@ struct sst_byt_priv_data { /* DAI data */ struct sst_byt_pcm_data pcm[BYT_PCM_COUNT]; + + /* flag indicating is stream context restore needed after suspend */ + bool restore_stream; }; /* this may get called several times by oss emulation */ @@ -184,7 +187,10 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) sst_byt_stream_start(byt, pcm_data->stream, 0); break; case SNDRV_PCM_TRIGGER_RESUME: - schedule_work(&pcm_data->work); + if (pdata->restore_stream == true) + schedule_work(&pcm_data->work); + else + sst_byt_stream_resume(byt, pcm_data->stream); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: sst_byt_stream_resume(byt, pcm_data->stream); @@ -193,6 +199,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) sst_byt_stream_stop(byt, pcm_data->stream); break; case SNDRV_PCM_TRIGGER_SUSPEND: + pdata->restore_stream = false; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: sst_byt_stream_pause(byt, pcm_data->stream); break; @@ -404,26 +411,10 @@ static const struct snd_soc_component_driver byt_dai_component = { }; #ifdef CONFIG_PM -static int sst_byt_pcm_dev_suspend_noirq(struct device *dev) -{ - struct sst_pdata *sst_pdata = dev_get_platdata(dev); - int ret; - - dev_dbg(dev, "suspending noirq\n"); - - /* at this point all streams will be stopped and context saved */ - ret = sst_byt_dsp_suspend_noirq(dev, sst_pdata); - if (ret < 0) { - dev_err(dev, "failed to suspend %d\n", ret); - return ret; - } - - return ret; -} - static int sst_byt_pcm_dev_suspend_late(struct device *dev) { struct sst_pdata *sst_pdata = dev_get_platdata(dev); + struct sst_byt_priv_data *priv_data = dev_get_drvdata(dev); int ret; dev_dbg(dev, "suspending late\n"); @@ -434,34 +425,30 @@ static int sst_byt_pcm_dev_suspend_late(struct device *dev) return ret; } + priv_data->restore_stream = true; + return ret; } static int sst_byt_pcm_dev_resume_early(struct device *dev) { struct sst_pdata *sst_pdata = dev_get_platdata(dev); + int ret; dev_dbg(dev, "resume early\n"); /* load fw and boot DSP */ - return sst_byt_dsp_boot(dev, sst_pdata); -} - -static int sst_byt_pcm_dev_resume(struct device *dev) -{ - struct sst_pdata *sst_pdata = dev_get_platdata(dev); - - dev_dbg(dev, "resume\n"); + ret = sst_byt_dsp_boot(dev, sst_pdata); + if (ret) + return ret; /* wait for FW to finish booting */ return sst_byt_dsp_wait_for_ready(dev, sst_pdata); } static const struct dev_pm_ops sst_byt_pm_ops = { - .suspend_noirq = sst_byt_pcm_dev_suspend_noirq, .suspend_late = sst_byt_pcm_dev_suspend_late, .resume_early = sst_byt_pcm_dev_resume_early, - .resume = sst_byt_pcm_dev_resume, }; #define SST_BYT_PM_OPS (&sst_byt_pm_ops) diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index f8a6adc2d81c..4336d1831485 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -260,7 +260,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { .stream_name = "TWL4030 Voice", .cpu_dai_name = "omap-mcbsp.3", .codec_dai_name = "twl4030-voice", - .platform_name = "omap-mcbsp.2", + .platform_name = "omap-mcbsp.3", .codec_name = "twl4030-codec", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM, diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 0109f6c2334e..a8e097433074 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -765,9 +765,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) +#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { .startup = pxa_ssp_startup, diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 8d8e4b59049f..fb9e05c9f471 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -165,13 +165,14 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, struct rk_i2s_dev *i2s = to_info(cpu_dai); unsigned int mask = 0, val = 0; - mask = I2S_CKR_MSS_SLAVE; + mask = I2S_CKR_MSS_MASK; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - val = I2S_CKR_MSS_SLAVE; + /* Set source clock in Master mode */ + val = I2S_CKR_MSS_MASTER; break; case SND_SOC_DAIFMT_CBM_CFM: - val = I2S_CKR_MSS_MASTER; + val = I2S_CKR_MSS_SLAVE; break; default: return -EINVAL; @@ -361,6 +362,8 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg) case I2S_XFER: case I2S_CLR: case I2S_RXDR: + case I2S_FIFOLR: + case I2S_INTSR: return true; default: return false; @@ -370,8 +373,8 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg) static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { - case I2S_FIFOLR: case I2S_INTSR: + case I2S_CLR: return true; default: return false; @@ -381,8 +384,6 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) { switch (reg) { - case I2S_FIFOLR: - return true; default: return false; } diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 03eec22f0f46..9d513473b300 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -462,7 +462,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, if (dir == SND_SOC_CLOCK_IN) rfs = 0; - if ((rfs && other->rfs && (other->rfs != rfs)) || + if ((rfs && other && other->rfs && (other->rfs != rfs)) || (any_active(i2s) && (((dir == SND_SOC_CLOCK_IN) && !(mod & MOD_CDCLKCON)) || @@ -762,7 +762,8 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, } else { u32 mod = readl(i2s->addr + I2SMOD); i2s->cdclk_out = !(mod & MOD_CDCLKCON); - other->cdclk_out = i2s->cdclk_out; + if (other) + other->cdclk_out = i2s->cdclk_out; } /* Reset any constraint on RFS and BFS */ i2s->rfs = 0; diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 3fdf3be7b99a..f95e7ab135e8 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -247,7 +247,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, }; /* it shouldn't happen */ - if (use_dvc & !use_src) + if (use_dvc && !use_src) dev_err(dev, "DVC is selected without SRC\n"); /* use SSIU or SSI ? */ diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 27c06acce205..3092b58fede6 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -101,7 +101,11 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream) fe->dpcm[stream].runtime = fe_substream->runtime; - if (dpcm_path_get(fe, stream, &list) <= 0) { + ret = dpcm_path_get(fe, stream, &list); + if (ret < 0) { + mutex_unlock(&fe->card->mutex); + goto fe_err; + } else if (ret == 0) { dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", fe->dai_link->name, stream ? "capture" : "playback"); } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d4bfd4a9076f..889f4e3d35dc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1325,7 +1325,7 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, device_initialize(rtd->dev); rtd->dev->parent = rtd->card->dev; rtd->dev->release = rtd_release; - rtd->dev->init_name = name; + dev_set_name(rtd->dev, "%s", name); dev_set_drvdata(rtd->dev, rtd); mutex_init(&rtd->pcm_mutex); INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8348352dc2c6..177bd8639ef9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2860,12 +2860,14 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int reg_val, val; - int ret = 0; - if (e->reg != SND_SOC_NOPM) - ret = soc_dapm_read(dapm, e->reg, ®_val); - else + if (e->reg != SND_SOC_NOPM) { + int ret = soc_dapm_read(dapm, e->reg, ®_val); + if (ret) + return ret; + } else { reg_val = dapm_kcontrol_get_value(kcontrol); + } val = (reg_val >> e->shift_l) & e->mask; ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); @@ -2875,7 +2877,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, ucontrol->value.enumerated.item[1] = val; } - return ret; + return 0; } EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 731fdb5b5f9b..642c86240752 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2352,7 +2352,11 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); fe->dpcm[stream].runtime = fe_substream->runtime; - if (dpcm_path_get(fe, stream, &list) <= 0) { + ret = dpcm_path_get(fe, stream, &list); + if (ret < 0) { + mutex_unlock(&fe->card->mutex); + return ret; + } else if (ret == 0) { dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", fe->dai_link->name, stream ? "capture" : "playback"); } diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 0e5a8f35d0ad..a7dc3c56f44d 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -4,7 +4,7 @@ * sound/soc/spear/spear_pcm.c * * Copyright (C) 2012 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.com> + * Rajeev Kumar<rajeevkumar.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -50,6 +50,6 @@ int devm_spear_pcm_platform_register(struct device *dev, } EXPORT_SYMBOL_GPL(devm_spear_pcm_platform_register); -MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); +MODULE_AUTHOR("Rajeev Kumar <rajeevkumar.linux@gmail.com>"); MODULE_DESCRIPTION("SPEAr PCM DMA module"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 9577121ce971..ca8037634100 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -21,7 +21,7 @@ */ #ifndef __TEGRA_ASOC_UTILS_H__ -#define __TEGRA_ASOC_UTILS_H_ +#define __TEGRA_ASOC_UTILS_H__ struct clk; struct device; diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index f65fc0987cfb..b7a7c805d63f 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c @@ -100,15 +100,19 @@ static int control_put(struct snd_kcontrol *kcontrol, struct snd_usb_caiaqdev *cdev = caiaqdev(chip->card); int pos = kcontrol->private_value; int v = ucontrol->value.integer.value[0]; - unsigned char cmd = EP1_CMD_WRITE_IO; + unsigned char cmd; - if (cdev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) - cmd = EP1_CMD_DIMM_LEDS; - - if (cdev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER)) + switch (cdev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): cmd = EP1_CMD_DIMM_LEDS; + break; + default: + cmd = EP1_CMD_WRITE_IO; + break; + } if (pos & CNT_INTVAL) { int i = pos & ~CNT_INTVAL; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index f652b10ce905..223c47b33ba3 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -1581,6 +1581,35 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { + /* BOSS ME-25 */ + USB_DEVICE(0x0582, 0x0113), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + }, + { + .ifnum = -1 + } + } + } +}, +{ /* only 44.1 kHz works at the moment */ USB_DEVICE(0x0582, 0x0120), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |