Merge branch 'fix/misc' into topic/misc
This commit is contained in:
Коммит
0308110615
|
@ -5532,6 +5532,7 @@ F: include/media/*7146*
|
||||||
|
|
||||||
SAMSUNG AUDIO (ASoC) DRIVERS
|
SAMSUNG AUDIO (ASoC) DRIVERS
|
||||||
M: Jassi Brar <jassisinghbrar@gmail.com>
|
M: Jassi Brar <jassisinghbrar@gmail.com>
|
||||||
|
M: Sangbeom Kim <sbkim73@samsung.com>
|
||||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||||
S: Supported
|
S: Supported
|
||||||
F: sound/soc/samsung
|
F: sound/soc/samsung
|
||||||
|
@ -7199,6 +7200,9 @@ W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/hwmon/wm83??
|
F: Documentation/hwmon/wm83??
|
||||||
F: drivers/leds/leds-wm83*.c
|
F: drivers/leds/leds-wm83*.c
|
||||||
|
F: drivers/input/misc/wm831x-on.c
|
||||||
|
F: drivers/input/touchscreen/wm831x-ts.c
|
||||||
|
F: drivers/input/touchscreen/wm97*.c
|
||||||
F: drivers/mfd/wm8*.c
|
F: drivers/mfd/wm8*.c
|
||||||
F: drivers/power/wm83*.c
|
F: drivers/power/wm83*.c
|
||||||
F: drivers/rtc/rtc-wm83*.c
|
F: drivers/rtc/rtc-wm83*.c
|
||||||
|
@ -7208,6 +7212,7 @@ F: drivers/watchdog/wm83*_wdt.c
|
||||||
F: include/linux/mfd/wm831x/
|
F: include/linux/mfd/wm831x/
|
||||||
F: include/linux/mfd/wm8350/
|
F: include/linux/mfd/wm8350/
|
||||||
F: include/linux/mfd/wm8400*
|
F: include/linux/mfd/wm8400*
|
||||||
|
F: include/linux/wm97xx.h
|
||||||
F: include/sound/wm????.h
|
F: include/sound/wm????.h
|
||||||
F: sound/soc/codecs/wm*
|
F: sound/soc/codecs/wm*
|
||||||
|
|
||||||
|
|
|
@ -1073,10 +1073,10 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
|
||||||
sdev->pcmid = -1;
|
sdev->pcmid = -1;
|
||||||
list_del(&ldev->list);
|
list_del(&ldev->list);
|
||||||
layouts_list_items--;
|
layouts_list_items--;
|
||||||
|
kfree(ldev);
|
||||||
outnodev:
|
outnodev:
|
||||||
of_node_put(sound);
|
of_node_put(sound);
|
||||||
layout_device = NULL;
|
layout_device = NULL;
|
||||||
kfree(ldev);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1761,6 +1761,10 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
||||||
snd_pcm_uframes_t avail = 0;
|
snd_pcm_uframes_t avail = 0;
|
||||||
long wait_time, tout;
|
long wait_time, tout;
|
||||||
|
|
||||||
|
init_waitqueue_entry(&wait, current);
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
add_wait_queue(&runtime->tsleep, &wait);
|
||||||
|
|
||||||
if (runtime->no_period_wakeup)
|
if (runtime->no_period_wakeup)
|
||||||
wait_time = MAX_SCHEDULE_TIMEOUT;
|
wait_time = MAX_SCHEDULE_TIMEOUT;
|
||||||
else {
|
else {
|
||||||
|
@ -1771,16 +1775,32 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
wait_time = msecs_to_jiffies(wait_time * 1000);
|
wait_time = msecs_to_jiffies(wait_time * 1000);
|
||||||
}
|
}
|
||||||
init_waitqueue_entry(&wait, current);
|
|
||||||
add_wait_queue(&runtime->tsleep, &wait);
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
err = -ERESTARTSYS;
|
err = -ERESTARTSYS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to check if space became available already
|
||||||
|
* (and thus the wakeup happened already) first to close
|
||||||
|
* the race of space already having become available.
|
||||||
|
* This check must happen after been added to the waitqueue
|
||||||
|
* and having current state be INTERRUPTIBLE.
|
||||||
|
*/
|
||||||
|
if (is_playback)
|
||||||
|
avail = snd_pcm_playback_avail(runtime);
|
||||||
|
else
|
||||||
|
avail = snd_pcm_capture_avail(runtime);
|
||||||
|
if (avail >= runtime->twake)
|
||||||
|
break;
|
||||||
snd_pcm_stream_unlock_irq(substream);
|
snd_pcm_stream_unlock_irq(substream);
|
||||||
tout = schedule_timeout_interruptible(wait_time);
|
|
||||||
|
tout = schedule_timeout(wait_time);
|
||||||
|
|
||||||
snd_pcm_stream_lock_irq(substream);
|
snd_pcm_stream_lock_irq(substream);
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
switch (runtime->status->state) {
|
switch (runtime->status->state) {
|
||||||
case SNDRV_PCM_STATE_SUSPENDED:
|
case SNDRV_PCM_STATE_SUSPENDED:
|
||||||
err = -ESTRPIPE;
|
err = -ESTRPIPE;
|
||||||
|
@ -1806,14 +1826,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (is_playback)
|
|
||||||
avail = snd_pcm_playback_avail(runtime);
|
|
||||||
else
|
|
||||||
avail = snd_pcm_capture_avail(runtime);
|
|
||||||
if (avail >= runtime->twake)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
_endloop:
|
_endloop:
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&runtime->tsleep, &wait);
|
remove_wait_queue(&runtime->tsleep, &wait);
|
||||||
*availp = avail;
|
*availp = avail;
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -579,9 +579,13 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
recursive++;
|
recursive++;
|
||||||
for (i = 0; i < nums; i++)
|
for (i = 0; i < nums; i++) {
|
||||||
|
unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
|
||||||
|
if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
|
||||||
|
continue;
|
||||||
if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
|
if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
|
EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
|
||||||
|
|
|
@ -144,25 +144,17 @@ static int cea_sampling_frequencies[8] = {
|
||||||
SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
|
SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
|
static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
|
||||||
int byte_index)
|
int byte_index)
|
||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
val = snd_hda_codec_read(codec, nid, 0,
|
val = snd_hda_codec_read(codec, nid, 0,
|
||||||
AC_VERB_GET_HDMI_ELDD, byte_index);
|
AC_VERB_GET_HDMI_ELDD, byte_index);
|
||||||
|
|
||||||
#ifdef BE_PARANOID
|
#ifdef BE_PARANOID
|
||||||
printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
|
printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
|
||||||
#endif
|
#endif
|
||||||
|
return val;
|
||||||
if ((val & AC_ELDD_ELD_VALID) == 0) {
|
|
||||||
snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
|
|
||||||
byte_index);
|
|
||||||
val = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val & AC_ELDD_ELD_DATA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GRAB_BITS(buf, byte, lowbit, bits) \
|
#define GRAB_BITS(buf, byte, lowbit, bits) \
|
||||||
|
@ -344,11 +336,26 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++) {
|
||||||
buf[i] = hdmi_get_eld_byte(codec, nid, i);
|
unsigned int val = hdmi_get_eld_data(codec, nid, i);
|
||||||
|
if (!(val & AC_ELDD_ELD_VALID)) {
|
||||||
|
if (!i) {
|
||||||
|
snd_printd(KERN_INFO
|
||||||
|
"HDMI: invalid ELD data\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
snd_printd(KERN_INFO
|
||||||
|
"HDMI: invalid ELD data byte %d\n", i);
|
||||||
|
val = 0;
|
||||||
|
} else
|
||||||
|
val &= AC_ELDD_ELD_DATA;
|
||||||
|
buf[i] = val;
|
||||||
|
}
|
||||||
|
|
||||||
ret = hdmi_update_eld(eld, buf, size);
|
ret = hdmi_update_eld(eld, buf, size);
|
||||||
|
|
||||||
|
error:
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,7 +375,7 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
|
||||||
static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
|
static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
|
||||||
unsigned int *idxp)
|
unsigned int *idxp)
|
||||||
{
|
{
|
||||||
int i;
|
int i, idx;
|
||||||
hda_nid_t nid;
|
hda_nid_t nid;
|
||||||
|
|
||||||
nid = codec->start_nid;
|
nid = codec->start_nid;
|
||||||
|
@ -384,9 +384,11 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
|
||||||
type = get_wcaps_type(get_wcaps(codec, nid));
|
type = get_wcaps_type(get_wcaps(codec, nid));
|
||||||
if (type != AC_WID_AUD_IN)
|
if (type != AC_WID_AUD_IN)
|
||||||
continue;
|
continue;
|
||||||
*idxp = snd_hda_get_conn_index(codec, nid, pin, false);
|
idx = snd_hda_get_conn_index(codec, nid, pin, false);
|
||||||
if (*idxp >= 0)
|
if (idx >= 0) {
|
||||||
|
*idxp = idx;
|
||||||
return nid;
|
return nid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +535,7 @@ static int add_volume(struct hda_codec *codec, const char *name,
|
||||||
int index, unsigned int pval, int dir,
|
int index, unsigned int pval, int dir,
|
||||||
struct snd_kcontrol **kctlp)
|
struct snd_kcontrol **kctlp)
|
||||||
{
|
{
|
||||||
char tmp[32];
|
char tmp[44];
|
||||||
struct snd_kcontrol_new knew =
|
struct snd_kcontrol_new knew =
|
||||||
HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
|
HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
|
||||||
knew.private_value = pval;
|
knew.private_value = pval;
|
||||||
|
|
|
@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
|
||||||
|
|
||||||
#define MAX_AUTO_DACS 5
|
#define MAX_AUTO_DACS 5
|
||||||
|
|
||||||
|
#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
|
||||||
|
|
||||||
/* fill analog DAC list from the widget tree */
|
/* fill analog DAC list from the widget tree */
|
||||||
static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
|
static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
|
||||||
{
|
{
|
||||||
|
@ -3370,16 +3372,26 @@ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
|
||||||
/* fill pin_dac_pair list from the pin and dac list */
|
/* fill pin_dac_pair list from the pin and dac list */
|
||||||
static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
|
static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
|
||||||
int num_pins, hda_nid_t *dacs, int *rest,
|
int num_pins, hda_nid_t *dacs, int *rest,
|
||||||
struct pin_dac_pair *filled, int type)
|
struct pin_dac_pair *filled, int nums,
|
||||||
|
int type)
|
||||||
{
|
{
|
||||||
int i, nums;
|
int i, start = nums;
|
||||||
|
|
||||||
nums = 0;
|
for (i = 0; i < num_pins; i++, nums++) {
|
||||||
for (i = 0; i < num_pins; i++) {
|
|
||||||
filled[nums].pin = pins[i];
|
filled[nums].pin = pins[i];
|
||||||
filled[nums].type = type;
|
filled[nums].type = type;
|
||||||
filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
|
filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
|
||||||
nums++;
|
if (filled[nums].dac)
|
||||||
|
continue;
|
||||||
|
if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
|
||||||
|
filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
|
||||||
|
filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
|
||||||
}
|
}
|
||||||
return nums;
|
return nums;
|
||||||
}
|
}
|
||||||
|
@ -3395,19 +3407,19 @@ static void cx_auto_parse_output(struct hda_codec *codec)
|
||||||
rest = fill_cx_auto_dacs(codec, dacs);
|
rest = fill_cx_auto_dacs(codec, dacs);
|
||||||
/* parse all analog output pins */
|
/* parse all analog output pins */
|
||||||
nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
|
nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
|
||||||
dacs, &rest, spec->dac_info,
|
dacs, &rest, spec->dac_info, 0,
|
||||||
AUTO_PIN_LINE_OUT);
|
AUTO_PIN_LINE_OUT);
|
||||||
nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
|
nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
|
||||||
dacs, &rest, spec->dac_info + nums,
|
dacs, &rest, spec->dac_info, nums,
|
||||||
AUTO_PIN_HP_OUT);
|
AUTO_PIN_HP_OUT);
|
||||||
nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
|
nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
|
||||||
dacs, &rest, spec->dac_info + nums,
|
dacs, &rest, spec->dac_info, nums,
|
||||||
AUTO_PIN_SPEAKER_OUT);
|
AUTO_PIN_SPEAKER_OUT);
|
||||||
spec->dac_info_filled = nums;
|
spec->dac_info_filled = nums;
|
||||||
/* fill multiout struct */
|
/* fill multiout struct */
|
||||||
for (i = 0; i < nums; i++) {
|
for (i = 0; i < nums; i++) {
|
||||||
hda_nid_t dac = spec->dac_info[i].dac;
|
hda_nid_t dac = spec->dac_info[i].dac;
|
||||||
if (!dac)
|
if (!dac || (dac & DAC_SLAVE_FLAG))
|
||||||
continue;
|
continue;
|
||||||
switch (spec->dac_info[i].type) {
|
switch (spec->dac_info[i].type) {
|
||||||
case AUTO_PIN_LINE_OUT:
|
case AUTO_PIN_LINE_OUT:
|
||||||
|
@ -3862,7 +3874,7 @@ static void cx_auto_parse_input(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
|
if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
|
||||||
cx_auto_check_auto_mic(codec);
|
cx_auto_check_auto_mic(codec);
|
||||||
if (imux->num_items > 1 && !spec->auto_mic) {
|
if (imux->num_items > 1) {
|
||||||
for (i = 1; i < imux->num_items; i++) {
|
for (i = 1; i < imux->num_items; i++) {
|
||||||
if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
|
if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
|
||||||
spec->adc_switching = 1;
|
spec->adc_switching = 1;
|
||||||
|
@ -4035,6 +4047,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
|
||||||
nid = spec->dac_info[i].dac;
|
nid = spec->dac_info[i].dac;
|
||||||
if (!nid)
|
if (!nid)
|
||||||
nid = spec->multiout.dac_nids[0];
|
nid = spec->multiout.dac_nids[0];
|
||||||
|
else if (nid & DAC_SLAVE_FLAG)
|
||||||
|
nid &= ~DAC_SLAVE_FLAG;
|
||||||
select_connection(codec, spec->dac_info[i].pin, nid);
|
select_connection(codec, spec->dac_info[i].pin, nid);
|
||||||
}
|
}
|
||||||
if (spec->auto_mute) {
|
if (spec->auto_mute) {
|
||||||
|
@ -4167,9 +4181,11 @@ static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
|
||||||
hda_nid_t pin, const char *name, int idx)
|
hda_nid_t pin, const char *name, int idx)
|
||||||
{
|
{
|
||||||
unsigned int caps;
|
unsigned int caps;
|
||||||
caps = query_amp_caps(codec, dac, HDA_OUTPUT);
|
if (dac && !(dac & DAC_SLAVE_FLAG)) {
|
||||||
if (caps & AC_AMPCAP_NUM_STEPS)
|
caps = query_amp_caps(codec, dac, HDA_OUTPUT);
|
||||||
return cx_auto_add_pb_volume(codec, dac, name, idx);
|
if (caps & AC_AMPCAP_NUM_STEPS)
|
||||||
|
return cx_auto_add_pb_volume(codec, dac, name, idx);
|
||||||
|
}
|
||||||
caps = query_amp_caps(codec, pin, HDA_OUTPUT);
|
caps = query_amp_caps(codec, pin, HDA_OUTPUT);
|
||||||
if (caps & AC_AMPCAP_NUM_STEPS)
|
if (caps & AC_AMPCAP_NUM_STEPS)
|
||||||
return cx_auto_add_pb_volume(codec, pin, name, idx);
|
return cx_auto_add_pb_volume(codec, pin, name, idx);
|
||||||
|
@ -4191,8 +4207,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
|
||||||
for (i = 0; i < spec->dac_info_filled; i++) {
|
for (i = 0; i < spec->dac_info_filled; i++) {
|
||||||
const char *label;
|
const char *label;
|
||||||
int idx, type;
|
int idx, type;
|
||||||
if (!spec->dac_info[i].dac)
|
hda_nid_t dac = spec->dac_info[i].dac;
|
||||||
continue;
|
|
||||||
type = spec->dac_info[i].type;
|
type = spec->dac_info[i].type;
|
||||||
if (type == AUTO_PIN_LINE_OUT)
|
if (type == AUTO_PIN_LINE_OUT)
|
||||||
type = spec->autocfg.line_out_type;
|
type = spec->autocfg.line_out_type;
|
||||||
|
@ -4211,7 +4226,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
|
||||||
idx = num_spk++;
|
idx = num_spk++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = try_add_pb_volume(codec, spec->dac_info[i].dac,
|
err = try_add_pb_volume(codec, dac,
|
||||||
spec->dac_info[i].pin,
|
spec->dac_info[i].pin,
|
||||||
label, idx);
|
label, idx);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -565,11 +565,11 @@ static void alc_hp_automute(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
|
|
||||||
if (!spec->automute)
|
|
||||||
return;
|
|
||||||
spec->jack_present =
|
spec->jack_present =
|
||||||
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
|
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
|
||||||
spec->autocfg.hp_pins);
|
spec->autocfg.hp_pins);
|
||||||
|
if (!spec->automute)
|
||||||
|
return;
|
||||||
update_speakers(codec);
|
update_speakers(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,11 +578,11 @@ static void alc_line_automute(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
|
|
||||||
if (!spec->automute || !spec->detect_line)
|
|
||||||
return;
|
|
||||||
spec->line_jack_present =
|
spec->line_jack_present =
|
||||||
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
|
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
|
||||||
spec->autocfg.line_out_pins);
|
spec->autocfg.line_out_pins);
|
||||||
|
if (!spec->automute || !spec->detect_line)
|
||||||
|
return;
|
||||||
update_speakers(codec);
|
update_speakers(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3083,16 +3083,22 @@ static void alc_auto_init_multi_out(struct hda_codec *codec)
|
||||||
static void alc_auto_init_extra_out(struct hda_codec *codec)
|
static void alc_auto_init_extra_out(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
hda_nid_t pin;
|
hda_nid_t pin, dac;
|
||||||
|
|
||||||
pin = spec->autocfg.hp_pins[0];
|
pin = spec->autocfg.hp_pins[0];
|
||||||
if (pin)
|
if (pin) {
|
||||||
alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
|
dac = spec->multiout.hp_nid;
|
||||||
spec->multiout.hp_nid);
|
if (!dac)
|
||||||
|
dac = spec->multiout.dac_nids[0];
|
||||||
|
alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
|
||||||
|
}
|
||||||
pin = spec->autocfg.speaker_pins[0];
|
pin = spec->autocfg.speaker_pins[0];
|
||||||
if (pin)
|
if (pin) {
|
||||||
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
|
dac = spec->multiout.extra_out_nid[0];
|
||||||
spec->multiout.extra_out_nid[0]);
|
if (!dac)
|
||||||
|
dac = spec->multiout.dac_nids[0];
|
||||||
|
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -56,7 +56,7 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
switch (params_rate(params)) {
|
switch (params_rate(params)) {
|
||||||
case 48000:
|
case 48000:
|
||||||
clk = 12288000;
|
clk = 24576000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
|
||||||
.cpu_dai_name = "bfin-tdm.0",
|
.cpu_dai_name = "bfin-tdm.0",
|
||||||
.codec_dai_name ="ad193x-hifi",
|
.codec_dai_name ="ad193x-hifi",
|
||||||
.platform_name = "bfin-tdm-pcm-audio",
|
.platform_name = "bfin-tdm-pcm-audio",
|
||||||
.codec_name = "ad193x.5",
|
.codec_name = "spi0.5",
|
||||||
.ops = &bf5xx_ad193x_ops,
|
.ops = &bf5xx_ad193x_ops,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
|
||||||
.cpu_dai_name = "bfin-tdm.1",
|
.cpu_dai_name = "bfin-tdm.1",
|
||||||
.codec_dai_name ="ad193x-hifi",
|
.codec_dai_name ="ad193x-hifi",
|
||||||
.platform_name = "bfin-tdm-pcm-audio",
|
.platform_name = "bfin-tdm-pcm-audio",
|
||||||
.codec_name = "ad193x.5",
|
.codec_name = "spi0.5",
|
||||||
.ops = &bf5xx_ad193x_ops,
|
.ops = &bf5xx_ad193x_ops,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,11 +27,6 @@ struct ad193x_priv {
|
||||||
int sysclk;
|
int sysclk;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ad193x register cache & default register settings */
|
|
||||||
static const u8 ad193x_reg[AD193X_NUM_REGS] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AD193X volume/mute/de-emphasis etc. controls
|
* AD193X volume/mute/de-emphasis etc. controls
|
||||||
*/
|
*/
|
||||||
|
@ -307,7 +302,8 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
|
||||||
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
|
snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg);
|
||||||
|
|
||||||
reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
|
reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
|
||||||
reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
|
reg = (reg & (~AD193X_DAC_WORD_LEN_MASK))
|
||||||
|
| (word_len << AD193X_DAC_WORD_LEN_SHFT);
|
||||||
snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
|
snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
|
||||||
|
|
||||||
reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
|
reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
|
||||||
|
@ -389,9 +385,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
|
||||||
|
|
||||||
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
|
static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
|
||||||
.probe = ad193x_probe,
|
.probe = ad193x_probe,
|
||||||
.reg_cache_default = ad193x_reg,
|
|
||||||
.reg_cache_size = AD193X_NUM_REGS,
|
|
||||||
.reg_word_size = sizeof(u16),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_SPI_MASTER)
|
#if defined(CONFIG_SPI_MASTER)
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
#define AD193X_DAC_LEFT_HIGH (1 << 3)
|
#define AD193X_DAC_LEFT_HIGH (1 << 3)
|
||||||
#define AD193X_DAC_BCLK_INV (1 << 7)
|
#define AD193X_DAC_BCLK_INV (1 << 7)
|
||||||
#define AD193X_DAC_CTRL2 0x804
|
#define AD193X_DAC_CTRL2 0x804
|
||||||
#define AD193X_DAC_WORD_LEN_MASK 0xC
|
#define AD193X_DAC_WORD_LEN_SHFT 3
|
||||||
|
#define AD193X_DAC_WORD_LEN_MASK 0x18
|
||||||
#define AD193X_DAC_MASTER_MUTE 1
|
#define AD193X_DAC_MASTER_MUTE 1
|
||||||
#define AD193X_DAC_CHNL_MUTE 0x805
|
#define AD193X_DAC_CHNL_MUTE 0x805
|
||||||
#define AD193X_DACL1_MUTE 0
|
#define AD193X_DACL1_MUTE 0
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
#define AD193X_ADC_CTRL1 0x80f
|
#define AD193X_ADC_CTRL1 0x80f
|
||||||
#define AD193X_ADC_SERFMT_MASK 0x60
|
#define AD193X_ADC_SERFMT_MASK 0x60
|
||||||
#define AD193X_ADC_SERFMT_STEREO (0 << 5)
|
#define AD193X_ADC_SERFMT_STEREO (0 << 5)
|
||||||
#define AD193X_ADC_SERFMT_TDM (1 << 2)
|
#define AD193X_ADC_SERFMT_TDM (1 << 5)
|
||||||
#define AD193X_ADC_SERFMT_AUX (2 << 5)
|
#define AD193X_ADC_SERFMT_AUX (2 << 5)
|
||||||
#define AD193X_ADC_WORD_LEN_MASK 0x3
|
#define AD193X_ADC_WORD_LEN_MASK 0x3
|
||||||
#define AD193X_ADC_CTRL2 0x810
|
#define AD193X_ADC_CTRL2 0x810
|
||||||
|
|
|
@ -857,6 +857,7 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
|
||||||
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
|
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
|
dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
|
||||||
|
kfree(sta32x);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2221,6 +2221,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
if (fll) {
|
if (fll) {
|
||||||
|
try_wait_for_completion(&wm8962->fll_lock);
|
||||||
|
|
||||||
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
|
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
|
||||||
WM8962_FLL_ENA, WM8962_FLL_ENA);
|
WM8962_FLL_ENA, WM8962_FLL_ENA);
|
||||||
if (wm8962->irq) {
|
if (wm8962->irq) {
|
||||||
|
@ -2927,10 +2929,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
|
||||||
WM8962_BIAS_ENA | 0x180);
|
WM8962_BIAS_ENA | 0x180);
|
||||||
|
|
||||||
msleep(5);
|
msleep(5);
|
||||||
|
|
||||||
snd_soc_update_bits(codec, WM8962_CLOCKING2,
|
|
||||||
WM8962_CLKREG_OVD,
|
|
||||||
WM8962_CLKREG_OVD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VMID 2*250k */
|
/* VMID 2*250k */
|
||||||
|
@ -3288,6 +3286,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||||
snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
|
snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
|
||||||
snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
|
snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
|
||||||
|
|
||||||
|
try_wait_for_completion(&wm8962->fll_lock);
|
||||||
|
|
||||||
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
|
snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
|
||||||
WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
|
WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
|
||||||
WM8962_FLL_ENA, fll1);
|
WM8962_FLL_ENA, fll1);
|
||||||
|
@ -3868,6 +3868,10 @@ static int wm8962_probe(struct snd_soc_codec *codec)
|
||||||
*/
|
*/
|
||||||
snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
|
snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
|
||||||
|
|
||||||
|
/* Ensure we have soft control over all registers */
|
||||||
|
snd_soc_update_bits(codec, WM8962_CLOCKING2,
|
||||||
|
WM8962_CLKREG_OVD, WM8962_CLKREG_OVD);
|
||||||
|
|
||||||
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
|
regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
|
||||||
|
|
||||||
if (pdata) {
|
if (pdata) {
|
||||||
|
|
|
@ -420,7 +420,7 @@ static const char *sidetone_hpf_text[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum sidetone_hpf =
|
static const struct soc_enum sidetone_hpf =
|
||||||
SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 6, sidetone_hpf_text);
|
SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 7, sidetone_hpf_text);
|
||||||
|
|
||||||
static const char *hpf_mode_text[] = {
|
static const char *hpf_mode_text[] = {
|
||||||
"HiFi", "Custom", "Voice"
|
"HiFi", "Custom", "Voice"
|
||||||
|
@ -988,15 +988,10 @@ SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),
|
||||||
SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
|
SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
|
SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
|
||||||
|
|
||||||
SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
|
SND_SOC_DAPM_MUX("IN1L Mux", WM8996_POWER_MANAGEMENT_7, 2, 0, &in1_mux),
|
||||||
SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
|
SND_SOC_DAPM_MUX("IN1R Mux", WM8996_POWER_MANAGEMENT_7, 3, 0, &in1_mux),
|
||||||
SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
|
SND_SOC_DAPM_MUX("IN2L Mux", WM8996_POWER_MANAGEMENT_7, 6, 0, &in2_mux),
|
||||||
SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
|
SND_SOC_DAPM_MUX("IN2R Mux", WM8996_POWER_MANAGEMENT_7, 7, 0, &in2_mux),
|
||||||
|
|
||||||
SND_SOC_DAPM_PGA("IN1L", WM8996_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
|
|
||||||
SND_SOC_DAPM_PGA("IN1R", WM8996_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
|
|
||||||
SND_SOC_DAPM_PGA("IN2L", WM8996_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
|
|
||||||
SND_SOC_DAPM_PGA("IN2R", WM8996_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
|
|
||||||
|
|
||||||
SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
|
SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
|
||||||
SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
|
SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
|
||||||
|
@ -1213,6 +1208,16 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
|
||||||
{ "AIF2RX0", NULL, "AIFCLK" },
|
{ "AIF2RX0", NULL, "AIFCLK" },
|
||||||
{ "AIF2RX1", NULL, "AIFCLK" },
|
{ "AIF2RX1", NULL, "AIFCLK" },
|
||||||
|
|
||||||
|
{ "AIF1TX0", NULL, "AIFCLK" },
|
||||||
|
{ "AIF1TX1", NULL, "AIFCLK" },
|
||||||
|
{ "AIF1TX2", NULL, "AIFCLK" },
|
||||||
|
{ "AIF1TX3", NULL, "AIFCLK" },
|
||||||
|
{ "AIF1TX4", NULL, "AIFCLK" },
|
||||||
|
{ "AIF1TX5", NULL, "AIFCLK" },
|
||||||
|
|
||||||
|
{ "AIF2TX0", NULL, "AIFCLK" },
|
||||||
|
{ "AIF2TX1", NULL, "AIFCLK" },
|
||||||
|
|
||||||
{ "DSP1RXL", NULL, "SYSDSPCLK" },
|
{ "DSP1RXL", NULL, "SYSDSPCLK" },
|
||||||
{ "DSP1RXR", NULL, "SYSDSPCLK" },
|
{ "DSP1RXR", NULL, "SYSDSPCLK" },
|
||||||
{ "DSP2RXL", NULL, "SYSDSPCLK" },
|
{ "DSP2RXL", NULL, "SYSDSPCLK" },
|
||||||
|
@ -2106,6 +2111,9 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
|
||||||
|
|
||||||
snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
|
snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda);
|
||||||
|
|
||||||
|
/* Clear any pending completions (eg, from failed startups) */
|
||||||
|
try_wait_for_completion(&wm8996->fll_lock);
|
||||||
|
|
||||||
snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
|
snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1,
|
||||||
WM8996_FLL_ENA, WM8996_FLL_ENA);
|
WM8996_FLL_ENA, WM8996_FLL_ENA);
|
||||||
|
|
||||||
|
|
|
@ -385,14 +385,14 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto fail;
|
goto fail_free_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->mem = request_mem_region(res->start, resource_size(res),
|
info->mem = request_mem_region(res->start, resource_size(res),
|
||||||
pdev->name);
|
pdev->name);
|
||||||
if (!info->mem) {
|
if (!info->mem) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto fail;
|
goto fail_free_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->regs = ioremap(info->mem->start, resource_size(info->mem));
|
info->regs = ioremap(info->mem->start, resource_size(info->mem));
|
||||||
|
@ -435,6 +435,7 @@ fail_unmap_mem:
|
||||||
iounmap(info->regs);
|
iounmap(info->regs);
|
||||||
fail_release_mem:
|
fail_release_mem:
|
||||||
release_mem_region(info->mem->start, resource_size(info->mem));
|
release_mem_region(info->mem->start, resource_size(info->mem));
|
||||||
|
fail_free_info:
|
||||||
kfree(info);
|
kfree(info);
|
||||||
fail:
|
fail:
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -879,10 +879,12 @@ static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
|
||||||
* assume that device_node pointers are a valid comparison.
|
* assume that device_node pointers are a valid comparison.
|
||||||
*/
|
*/
|
||||||
np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
|
np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
|
||||||
|
of_node_put(np);
|
||||||
if (np == dma_channel_np)
|
if (np == dma_channel_np)
|
||||||
return ssi_np;
|
return ssi_np;
|
||||||
|
|
||||||
np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
|
np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
|
||||||
|
of_node_put(np);
|
||||||
if (np == dma_channel_np)
|
if (np == dma_channel_np)
|
||||||
return ssi_np;
|
return ssi_np;
|
||||||
}
|
}
|
||||||
|
|
|
@ -369,7 +369,7 @@ static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
|
||||||
.pcm_free = &psc_dma_free,
|
.pcm_free = &psc_dma_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mpc5200_hpcd_probe(struct of_device *op)
|
static int mpc5200_hpcd_probe(struct platform_device *op)
|
||||||
{
|
{
|
||||||
phys_addr_t fifo;
|
phys_addr_t fifo;
|
||||||
struct psc_dma *psc_dma;
|
struct psc_dma *psc_dma;
|
||||||
|
@ -487,7 +487,7 @@ out_unmap:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mpc5200_hpcd_remove(struct of_device *op)
|
static int mpc5200_hpcd_remove(struct platform_device *op)
|
||||||
{
|
{
|
||||||
struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
|
struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
|
||||||
|
|
||||||
|
@ -519,7 +519,7 @@ MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
|
||||||
static struct platform_driver mpc5200_hpcd_of_driver = {
|
static struct platform_driver mpc5200_hpcd_of_driver = {
|
||||||
.probe = mpc5200_hpcd_probe,
|
.probe = mpc5200_hpcd_probe,
|
||||||
.remove = mpc5200_hpcd_remove,
|
.remove = mpc5200_hpcd_remove,
|
||||||
.dev = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "mpc5200-pcm-audio",
|
.name = "mpc5200-pcm-audio",
|
||||||
.of_match_table = mpc5200_hpcd_match,
|
.of_match_table = mpc5200_hpcd_match,
|
||||||
|
|
|
@ -345,8 +345,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
|
machine_data = kzalloc(sizeof(struct mpc8610_hpcd_data), GFP_KERNEL);
|
||||||
if (!machine_data)
|
if (!machine_data) {
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto error_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
|
machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
|
||||||
machine_data->dai[0].ops = &mpc8610_hpcd_ops;
|
machine_data->dai[0].ops = &mpc8610_hpcd_ops;
|
||||||
|
@ -494,7 +496,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
|
||||||
ret = platform_device_add(sound_device);
|
ret = platform_device_add(sound_device);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "platform device add failed\n");
|
dev_err(&pdev->dev, "platform device add failed\n");
|
||||||
goto error;
|
goto error_sound;
|
||||||
}
|
}
|
||||||
dev_set_drvdata(&pdev->dev, sound_device);
|
dev_set_drvdata(&pdev->dev, sound_device);
|
||||||
|
|
||||||
|
@ -502,14 +504,12 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_sound:
|
||||||
|
platform_device_unregister(sound_device);
|
||||||
error:
|
error:
|
||||||
of_node_put(codec_np);
|
|
||||||
|
|
||||||
if (sound_device)
|
|
||||||
platform_device_unregister(sound_device);
|
|
||||||
|
|
||||||
kfree(machine_data);
|
kfree(machine_data);
|
||||||
|
error_alloc:
|
||||||
|
of_node_put(codec_np);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,8 +297,10 @@ static int get_dma_channel(struct device_node *ssi_np,
|
||||||
* dai->platform name should already point to an allocated buffer.
|
* dai->platform name should already point to an allocated buffer.
|
||||||
*/
|
*/
|
||||||
ret = of_address_to_resource(dma_channel_np, 0, &res);
|
ret = of_address_to_resource(dma_channel_np, 0, &res);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
of_node_put(dma_channel_np);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
|
snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
|
||||||
(unsigned long long) res.start, dma_channel_np->name);
|
(unsigned long long) res.start, dma_channel_np->name);
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,6 @@ static int ssi_irq = 0;
|
||||||
|
|
||||||
static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
|
static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_card *card = rtd->card->snd_card;
|
|
||||||
struct snd_soc_dai *dai = rtd->cpu_dai;
|
struct snd_soc_dai *dai = rtd->cpu_dai;
|
||||||
struct snd_pcm *pcm = rtd->pcm;
|
struct snd_pcm *pcm = rtd->pcm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -424,7 +424,7 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
|
||||||
if (!priv->mem) {
|
if (!priv->mem) {
|
||||||
dev_err(&pdev->dev, "request_mem_region failed\n");
|
dev_err(&pdev->dev, "request_mem_region failed\n");
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto error;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->io = ioremap(priv->mem->start, SZ_16K);
|
priv->io = ioremap(priv->mem->start, SZ_16K);
|
||||||
|
|
|
@ -514,7 +514,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set codec bias level */
|
/* Set codec bias level */
|
||||||
ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY);
|
ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY);
|
||||||
|
|
||||||
/* Add hook switch - can be used to control the codec from userspace
|
/* Add hook switch - can be used to control the codec from userspace
|
||||||
* even if line discipline fails */
|
* even if line discipline fails */
|
||||||
|
@ -649,7 +649,9 @@ static void __exit ams_delta_module_exit(void)
|
||||||
ams_delta_hook_switch_gpios);
|
ams_delta_hook_switch_gpios);
|
||||||
|
|
||||||
/* Keep modem power on */
|
/* Keep modem power on */
|
||||||
ams_delta_set_bias_level(&ams_delta_audio_card, SND_SOC_BIAS_STANDBY);
|
ams_delta_set_bias_level(&ams_delta_audio_card,
|
||||||
|
&ams_delta_audio_card.rtd[0].codec->dapm,
|
||||||
|
SND_SOC_BIAS_STANDBY);
|
||||||
|
|
||||||
platform_device_unregister(cx20442_platform_device);
|
platform_device_unregister(cx20442_platform_device);
|
||||||
platform_device_unregister(ams_delta_audio_platform_device);
|
platform_device_unregister(ams_delta_audio_platform_device);
|
||||||
|
|
|
@ -185,6 +185,7 @@ config SND_SOC_SPEYSIDE
|
||||||
select SND_SAMSUNG_I2S
|
select SND_SAMSUNG_I2S
|
||||||
select SND_SOC_WM8996
|
select SND_SOC_WM8996
|
||||||
select SND_SOC_WM9081
|
select SND_SOC_WM9081
|
||||||
|
select SND_SOC_WM1250_EV1
|
||||||
|
|
||||||
config SND_SOC_SPEYSIDE_WM8962
|
config SND_SOC_SPEYSIDE_WM8962
|
||||||
tristate "Audio support for Wolfson Speyside with WM8962"
|
tristate "Audio support for Wolfson Speyside with WM8962"
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
|
|
@ -23,6 +23,9 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card,
|
||||||
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
|
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (dapm->dev != codec_dai->dev)
|
||||||
|
return 0;
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SND_SOC_BIAS_PREPARE:
|
case SND_SOC_BIAS_PREPARE:
|
||||||
if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
|
if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
|
||||||
|
@ -57,6 +60,9 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card,
|
||||||
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
|
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (dapm->dev != codec_dai->dev)
|
||||||
|
return 0;
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SND_SOC_BIAS_STANDBY:
|
case SND_SOC_BIAS_STANDBY:
|
||||||
ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
|
ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
|
||||||
|
|
|
@ -203,14 +203,14 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
|
||||||
rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
|
rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
|
||||||
for (i = 0; i < rbnode->blklen; ++i) {
|
for (i = 0; i < rbnode->blklen; ++i) {
|
||||||
regtmp = rbnode->base_reg + i;
|
regtmp = rbnode->base_reg + i;
|
||||||
WARN_ON(codec->writable_register &&
|
|
||||||
codec->writable_register(codec, regtmp));
|
|
||||||
val = snd_soc_rbtree_get_register(rbnode, i);
|
val = snd_soc_rbtree_get_register(rbnode, i);
|
||||||
def = snd_soc_get_cache_val(codec->reg_def_copy, i,
|
def = snd_soc_get_cache_val(codec->reg_def_copy, i,
|
||||||
rbnode->word_size);
|
rbnode->word_size);
|
||||||
if (val == def)
|
if (val == def)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
WARN_ON(!snd_soc_codec_writable_register(codec, regtmp));
|
||||||
|
|
||||||
codec->cache_bypass = 1;
|
codec->cache_bypass = 1;
|
||||||
ret = snd_soc_write(codec, regtmp, val);
|
ret = snd_soc_write(codec, regtmp, val);
|
||||||
codec->cache_bypass = 0;
|
codec->cache_bypass = 0;
|
||||||
|
@ -563,8 +563,7 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
|
||||||
|
|
||||||
lzo_blocks = codec->reg_cache;
|
lzo_blocks = codec->reg_cache;
|
||||||
for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
|
for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
|
||||||
WARN_ON(codec->writable_register &&
|
WARN_ON(!snd_soc_codec_writable_register(codec, i));
|
||||||
codec->writable_register(codec, i));
|
|
||||||
ret = snd_soc_cache_read(codec, i, &val);
|
ret = snd_soc_cache_read(codec, i, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -823,8 +822,6 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
||||||
|
|
||||||
codec_drv = codec->driver;
|
codec_drv = codec->driver;
|
||||||
for (i = 0; i < codec_drv->reg_cache_size; ++i) {
|
for (i = 0; i < codec_drv->reg_cache_size; ++i) {
|
||||||
WARN_ON(codec->writable_register &&
|
|
||||||
codec->writable_register(codec, i));
|
|
||||||
ret = snd_soc_cache_read(codec, i, &val);
|
ret = snd_soc_cache_read(codec, i, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -832,6 +829,9 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
|
||||||
if (snd_soc_get_cache_val(codec->reg_def_copy,
|
if (snd_soc_get_cache_val(codec->reg_def_copy,
|
||||||
i, codec_drv->reg_word_size) == val)
|
i, codec_drv->reg_word_size) == val)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
WARN_ON(!snd_soc_codec_writable_register(codec, i));
|
||||||
|
|
||||||
ret = snd_soc_write(codec, i, val);
|
ret = snd_soc_write(codec, i, val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1633,7 +1633,7 @@ int snd_soc_codec_readable_register(struct snd_soc_codec *codec,
|
||||||
if (codec->readable_register)
|
if (codec->readable_register)
|
||||||
return codec->readable_register(codec, reg);
|
return codec->readable_register(codec, reg);
|
||||||
else
|
else
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
|
EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register);
|
||||||
|
|
||||||
|
@ -1651,7 +1651,7 @@ int snd_soc_codec_writable_register(struct snd_soc_codec *codec,
|
||||||
if (codec->writable_register)
|
if (codec->writable_register)
|
||||||
return codec->writable_register(codec, reg);
|
return codec->writable_register(codec, reg);
|
||||||
else
|
else
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
|
EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register);
|
||||||
|
|
||||||
|
@ -1913,7 +1913,7 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
|
||||||
|
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
name_len = strlen(long_name) + strlen(prefix) + 2;
|
name_len = strlen(long_name) + strlen(prefix) + 2;
|
||||||
name = kmalloc(name_len, GFP_ATOMIC);
|
name = kmalloc(name_len, GFP_KERNEL);
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -2763,7 +2763,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_soc_dapm_free - free dapm resources
|
* snd_soc_dapm_free - free dapm resources
|
||||||
* @card: SoC device
|
* @dapm: DAPM context
|
||||||
*
|
*
|
||||||
* Free all dapm widgets and resources.
|
* Free all dapm widgets and resources.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -205,6 +205,25 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
|
||||||
#define snd_soc_16_8_read_i2c NULL
|
#define snd_soc_16_8_read_i2c NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SPI_MASTER)
|
||||||
|
static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec,
|
||||||
|
unsigned int r)
|
||||||
|
{
|
||||||
|
struct spi_device *spi = codec->control_data;
|
||||||
|
|
||||||
|
const u16 reg = cpu_to_be16(r | 0x100);
|
||||||
|
u8 data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = spi_write_then_read(spi, ®, 2, &data, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define snd_soc_16_8_read_spi NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
|
static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
|
||||||
unsigned int value)
|
unsigned int value)
|
||||||
{
|
{
|
||||||
|
@ -295,6 +314,7 @@ static struct {
|
||||||
int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
|
int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
|
||||||
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
|
||||||
unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
|
unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
|
||||||
|
unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int);
|
||||||
} io_types[] = {
|
} io_types[] = {
|
||||||
{
|
{
|
||||||
.addr_bits = 4, .data_bits = 12,
|
.addr_bits = 4, .data_bits = 12,
|
||||||
|
@ -318,6 +338,7 @@ static struct {
|
||||||
.addr_bits = 16, .data_bits = 8,
|
.addr_bits = 16, .data_bits = 8,
|
||||||
.write = snd_soc_16_8_write,
|
.write = snd_soc_16_8_write,
|
||||||
.i2c_read = snd_soc_16_8_read_i2c,
|
.i2c_read = snd_soc_16_8_read_i2c,
|
||||||
|
.spi_read = snd_soc_16_8_read_spi,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.addr_bits = 16, .data_bits = 16,
|
.addr_bits = 16, .data_bits = 16,
|
||||||
|
@ -383,6 +404,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
|
||||||
#ifdef CONFIG_SPI_MASTER
|
#ifdef CONFIG_SPI_MASTER
|
||||||
codec->hw_write = do_spi_write;
|
codec->hw_write = do_spi_write;
|
||||||
#endif
|
#endif
|
||||||
|
if (io_types[i].spi_read)
|
||||||
|
codec->hw_read = io_types[i].spi_read;
|
||||||
|
|
||||||
codec->control_data = container_of(codec->dev,
|
codec->control_data = container_of(codec->dev,
|
||||||
struct spi_device,
|
struct spi_device,
|
||||||
|
|
|
@ -105,7 +105,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
|
||||||
|
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
snd_jack_report(jack->jack, status);
|
snd_jack_report(jack->jack, jack->status);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&codec->mutex);
|
mutex_unlock(&codec->mutex);
|
||||||
|
@ -327,7 +327,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||||
IRQF_TRIGGER_FALLING,
|
IRQF_TRIGGER_FALLING,
|
||||||
gpios[i].name,
|
gpios[i].name,
|
||||||
&gpios[i]);
|
&gpios[i]);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (gpios[i].wake) {
|
if (gpios[i].wake) {
|
||||||
|
|
|
@ -290,6 +290,9 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
|
||||||
codec_dai->active--;
|
codec_dai->active--;
|
||||||
codec->active--;
|
codec->active--;
|
||||||
|
|
||||||
|
if (!cpu_dai->active && !codec_dai->active)
|
||||||
|
rtd->rate = 0;
|
||||||
|
|
||||||
/* Muting the DAC suppresses artifacts caused during digital
|
/* Muting the DAC suppresses artifacts caused during digital
|
||||||
* shutdown, for example from stopping clocks.
|
* shutdown, for example from stopping clocks.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -319,7 +319,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
|
snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
|
||||||
|
|
||||||
/* FIXME: Calculate automatically based on DAPM routes? */
|
/* FIXME: Calculate automatically based on DAPM routes? */
|
||||||
if (!machine_is_harmony() && !machine_is_ventana())
|
if (!machine_is_harmony())
|
||||||
snd_soc_dapm_nc_pin(dapm, "IN1L");
|
snd_soc_dapm_nc_pin(dapm, "IN1L");
|
||||||
if (!machine_is_seaboard() && !machine_is_aebl())
|
if (!machine_is_seaboard() && !machine_is_aebl())
|
||||||
snd_soc_dapm_nc_pin(dapm, "IN1R");
|
snd_soc_dapm_nc_pin(dapm, "IN1R");
|
||||||
|
@ -395,7 +395,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
|
||||||
platform_set_drvdata(pdev, card);
|
platform_set_drvdata(pdev, card);
|
||||||
snd_soc_card_set_drvdata(card, machine);
|
snd_soc_card_set_drvdata(card, machine);
|
||||||
|
|
||||||
if (machine_is_harmony() || machine_is_ventana()) {
|
if (machine_is_harmony()) {
|
||||||
card->dapm_routes = harmony_audio_map;
|
card->dapm_routes = harmony_audio_map;
|
||||||
card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
|
card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
|
||||||
} else if (machine_is_seaboard()) {
|
} else if (machine_is_seaboard()) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче