Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 353259
b: refs/heads/master
c: 825315b
h: refs/heads/master
i:
  353257: aea5d2a
  353255: 8c7880a
v: v3
  • Loading branch information
Ian Minett authored and Takashi Iwai committed Jan 15, 2013
1 parent 6fc970f commit 762a262
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a7e76271bdca5b85adb42fed05aae10ff6adeef3
refs/heads/master: 825315bc5b5c33e5af5124ff100ef05a30ad722f
131 changes: 118 additions & 13 deletions trunk/sound/pci/hda/patch_ca0132.c
Original file line number Diff line number Diff line change
Expand Up @@ -2630,34 +2630,92 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir)

/*
* PCM callbacks
* PCM stuffs
*/
static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag,
int channel_id, int format)
{
struct ca0132_spec *spec = codec->spec;
return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
hinfo);
unsigned int oldval, newval;

if (!nid)
return;

snd_printdd(
"ca0132_setup_stream: NID=0x%x, stream=0x%x, "
"channel=%d, format=0x%x\n",
nid, stream_tag, channel_id, format);

/* update the format-id if changed */
oldval = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_STREAM_FORMAT,
0);
if (oldval != format) {
msleep(20);
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_STREAM_FORMAT,
format);
}

oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
newval = (stream_tag << 4) | channel_id;
if (oldval != newval) {
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_CHANNEL_STREAMID,
newval);
}
}

static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
{
unsigned int val;

if (!nid)
return;

snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid);

val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
if (!val)
return;

snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
}

/*
* PCM callbacks
*/
static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
struct ca0132_spec *spec = codec->spec;
return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
stream_tag, format, substream);

ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);

return 0;
}

static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct ca0132_spec *spec = codec->spec;
return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);

if (spec->dsp_state == DSP_DOWNLOADING)
return 0;

/*If Playback effects are on, allow stream some time to flush
*effects tail*/
if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
msleep(50);

ca0132_cleanup_stream(codec, spec->dacs[0]);

return 0;
}

/*
Expand Down Expand Up @@ -2698,6 +2756,36 @@ static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}

/*
* Analog capture
*/
static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
struct ca0132_spec *spec = codec->spec;

ca0132_setup_stream(codec, spec->adcs[substream->number],
stream_tag, 0, format);

return 0;
}

static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct ca0132_spec *spec = codec->spec;

if (spec->dsp_state == DSP_DOWNLOADING)
return 0;

ca0132_cleanup_stream(codec, hinfo->nid);
return 0;
}

/*
* Select the active output.
* If autodetect is enabled, output will be selected based on jack detection.
Expand Down Expand Up @@ -3509,9 +3597,8 @@ static struct snd_kcontrol_new ca0132_mixer[] = {
static struct hda_pcm_stream ca0132_pcm_analog_playback = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
.channels_max = 6,
.ops = {
.open = ca0132_playback_pcm_open,
.prepare = ca0132_playback_pcm_prepare,
.cleanup = ca0132_playback_pcm_cleanup
},
Expand All @@ -3521,6 +3608,10 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
.substreams = 1,
.channels_min = 2,
.channels_max = 2,
.ops = {
.prepare = ca0132_capture_pcm_prepare,
.cleanup = ca0132_capture_pcm_cleanup
},
};

static struct hda_pcm_stream ca0132_pcm_digital_playback = {
Expand Down Expand Up @@ -3555,10 +3646,24 @@ static int ca0132_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
spec->multiout.max_channels;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
codec->num_pcms++;

info++;
info->name = "CA0132 Analog Mic-In2";
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
codec->num_pcms++;

info++;
info->name = "CA0132 What U Hear";
info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[2];
codec->num_pcms++;

if (!spec->dig_out && !spec->dig_in)
return 0;

Expand Down

0 comments on commit 762a262

Please sign in to comment.