aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_ca0132.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 748fca78131c..9ea5660e1a3a 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1172,6 +1172,59 @@ static int dspio_write_multiple(struct hda_codec *codec,
1172 return status; 1172 return status;
1173} 1173}
1174 1174
1175static int dspio_read(struct hda_codec *codec, unsigned int *data)
1176{
1177 int status;
1178
1179 status = dspio_send(codec, VENDOR_DSPIO_SCP_POST_READ_DATA, 0);
1180 if (status == -EIO)
1181 return status;
1182
1183 status = dspio_send(codec, VENDOR_DSPIO_STATUS, 0);
1184 if (status == -EIO ||
1185 status == VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY)
1186 return -EIO;
1187
1188 *data = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0,
1189 VENDOR_DSPIO_SCP_READ_DATA, 0);
1190
1191 return 0;
1192}
1193
1194static int dspio_read_multiple(struct hda_codec *codec, unsigned int *buffer,
1195 unsigned int *buf_size, unsigned int size_count)
1196{
1197 int status = 0;
1198 unsigned int size = *buf_size;
1199 unsigned int count;
1200 unsigned int skip_count;
1201 unsigned int dummy;
1202
1203 if ((buffer == NULL))
1204 return -1;
1205
1206 count = 0;
1207 while (count < size && count < size_count) {
1208 status = dspio_read(codec, buffer++);
1209 if (status != 0)
1210 break;
1211 count++;
1212 }
1213
1214 skip_count = count;
1215 if (status == 0) {
1216 while (skip_count < size) {
1217 status = dspio_read(codec, &dummy);
1218 if (status != 0)
1219 break;
1220 skip_count++;
1221 }
1222 }
1223 *buf_size = count;
1224
1225 return status;
1226}
1227
1175/* 1228/*
1176 * Construct the SCP header using corresponding fields 1229 * Construct the SCP header using corresponding fields
1177 */ 1230 */
@@ -1231,6 +1284,38 @@ struct scp_msg {
1231 unsigned int data[SCP_MAX_DATA_WORDS]; 1284 unsigned int data[SCP_MAX_DATA_WORDS];
1232}; 1285};
1233 1286
1287static void dspio_clear_response_queue(struct hda_codec *codec)
1288{
1289 unsigned int dummy = 0;
1290 int status = -1;
1291
1292 /* clear all from the response queue */
1293 do {
1294 status = dspio_read(codec, &dummy);
1295 } while (status == 0);
1296}
1297
1298static int dspio_get_response_data(struct hda_codec *codec)
1299{
1300 struct ca0132_spec *spec = codec->spec;
1301 unsigned int data = 0;
1302 unsigned int count;
1303
1304 if (dspio_read(codec, &data) < 0)
1305 return -EIO;
1306
1307 if ((data & 0x00ffffff) == spec->wait_scp_header) {
1308 spec->scp_resp_header = data;
1309 spec->scp_resp_count = data >> 27;
1310 count = spec->wait_num_data;
1311 dspio_read_multiple(codec, spec->scp_resp_data,
1312 &spec->scp_resp_count, count);
1313 return 0;
1314 }
1315
1316 return -EIO;
1317}
1318
1234/* 1319/*
1235 * Send SCP message to DSP 1320 * Send SCP message to DSP
1236 */ 1321 */
@@ -3743,6 +3828,12 @@ static int ca0132_build_controls(struct hda_codec *codec)
3743 return 0; 3828 return 0;
3744} 3829}
3745 3830
3831static void ca0132_init_unsol(struct hda_codec *codec)
3832{
3833 snd_hda_jack_detect_enable(codec, UNSOL_TAG_HP, UNSOL_TAG_HP);
3834 snd_hda_jack_detect_enable(codec, UNSOL_TAG_AMIC1, UNSOL_TAG_AMIC1);
3835}
3836
3746static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir) 3837static void refresh_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir)
3747{ 3838{
3748 unsigned int caps; 3839 unsigned int caps;
@@ -4152,6 +4243,47 @@ static void ca0132_download_dsp(struct hda_codec *codec)
4152 ca0132_set_dsp_msr(codec, true); 4243 ca0132_set_dsp_msr(codec, true);
4153} 4244}
4154 4245
4246static void ca0132_process_dsp_response(struct hda_codec *codec)
4247{
4248 struct ca0132_spec *spec = codec->spec;
4249
4250 snd_printdd(KERN_INFO "ca0132_process_dsp_response\n");
4251 if (spec->wait_scp) {
4252 if (dspio_get_response_data(codec) >= 0)
4253 spec->wait_scp = 0;
4254 }
4255
4256 dspio_clear_response_queue(codec);
4257}
4258
4259static void ca0132_unsol_event(struct hda_codec *codec, unsigned int res)
4260{
4261 snd_printdd(KERN_INFO "ca0132_unsol_event: 0x%x\n", res);
4262
4263
4264 if (((res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f) == UNSOL_TAG_DSP) {
4265 ca0132_process_dsp_response(codec);
4266 } else {
4267 res = snd_hda_jack_get_action(codec,
4268 (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x3f);
4269
4270 snd_printdd(KERN_INFO "snd_hda_jack_get_action: 0x%x\n", res);
4271
4272 switch (res) {
4273 case UNSOL_TAG_HP:
4274 ca0132_select_out(codec);
4275 snd_hda_jack_report_sync(codec);
4276 break;
4277 case UNSOL_TAG_AMIC1:
4278 ca0132_select_mic(codec);
4279 snd_hda_jack_report_sync(codec);
4280 break;
4281 default:
4282 break;
4283 }
4284 }
4285}
4286
4155static int ca0132_init(struct hda_codec *codec) 4287static int ca0132_init(struct hda_codec *codec)
4156{ 4288{
4157 struct ca0132_spec *spec = codec->spec; 4289 struct ca0132_spec *spec = codec->spec;
@@ -4187,9 +4319,13 @@ static int ca0132_init(struct hda_codec *codec)
4187 for (i = 0; i < spec->num_init_verbs; i++) 4319 for (i = 0; i < spec->num_init_verbs; i++)
4188 snd_hda_sequence_write(codec, spec->init_verbs[i]); 4320 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4189 4321
4322 ca0132_init_unsol(codec);
4323
4190 ca0132_select_out(codec); 4324 ca0132_select_out(codec);
4191 ca0132_select_mic(codec); 4325 ca0132_select_mic(codec);
4192 4326
4327 snd_hda_jack_report_sync(codec);
4328
4193 snd_hda_power_down(codec); 4329 snd_hda_power_down(codec);
4194 4330
4195 return 0; 4331 return 0;
@@ -4211,11 +4347,13 @@ static struct hda_codec_ops ca0132_patch_ops = {
4211 .build_pcms = ca0132_build_pcms, 4347 .build_pcms = ca0132_build_pcms,
4212 .init = ca0132_init, 4348 .init = ca0132_init,
4213 .free = ca0132_free, 4349 .free = ca0132_free,
4350 .unsol_event = ca0132_unsol_event,
4214}; 4351};
4215 4352
4216static int patch_ca0132(struct hda_codec *codec) 4353static int patch_ca0132(struct hda_codec *codec)
4217{ 4354{
4218 struct ca0132_spec *spec; 4355 struct ca0132_spec *spec;
4356 int err;
4219 4357
4220 snd_printdd("patch_ca0132\n"); 4358 snd_printdd("patch_ca0132\n");
4221 4359
@@ -4237,6 +4375,10 @@ static int patch_ca0132(struct hda_codec *codec)
4237 4375
4238 ca0132_config(codec); 4376 ca0132_config(codec);
4239 4377
4378 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4379 if (err < 0)
4380 return err;
4381
4240 codec->patch_ops = ca0132_patch_ops; 4382 codec->patch_ops = ca0132_patch_ops;
4241 4383
4242 return 0; 4384 return 0;