diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 45ddf548d6fb..240958df26ce 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1148,6 +1148,166 @@ static int patch_stac927x(struct hda_codec *codec) | |||
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | /* | 1150 | /* |
1151 | * STAC 7661(?) hack | ||
1152 | */ | ||
1153 | |||
1154 | /* static config for Sony VAIO FE550G */ | ||
1155 | static hda_nid_t vaio_dacs[] = { 0x2 }; | ||
1156 | #define VAIO_HP_DAC 0x5 | ||
1157 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | ||
1158 | static hda_nid_t vaio_mux_nids[] = { 0x15 }; | ||
1159 | |||
1160 | static struct hda_input_mux vaio_mux = { | ||
1161 | .num_items = 2, | ||
1162 | .items = { | ||
1163 | /* { "HP", 0x0 }, | ||
1164 | { "Unknown", 0x1 }, */ | ||
1165 | { "Mic", 0x2 }, | ||
1166 | { "PCM", 0x3 }, | ||
1167 | } | ||
1168 | }; | ||
1169 | |||
1170 | static struct hda_verb vaio_init[] = { | ||
1171 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
1172 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
1173 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
1174 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
1175 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
1176 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ | ||
1177 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
1178 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
1179 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
1180 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
1181 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
1182 | {} | ||
1183 | }; | ||
1184 | |||
1185 | /* bind volumes of both NID 0x02 and 0x05 */ | ||
1186 | static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, | ||
1187 | struct snd_ctl_elem_value *ucontrol) | ||
1188 | { | ||
1189 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1190 | long *valp = ucontrol->value.integer.value; | ||
1191 | int change; | ||
1192 | |||
1193 | change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, | ||
1194 | 0x7f, valp[0] & 0x7f); | ||
1195 | change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, | ||
1196 | 0x7f, valp[1] & 0x7f); | ||
1197 | snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1198 | 0x7f, valp[0] & 0x7f); | ||
1199 | snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1200 | 0x7f, valp[1] & 0x7f); | ||
1201 | return change; | ||
1202 | } | ||
1203 | |||
1204 | /* bind volumes of both NID 0x02 and 0x05 */ | ||
1205 | static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, | ||
1206 | struct snd_ctl_elem_value *ucontrol) | ||
1207 | { | ||
1208 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1209 | long *valp = ucontrol->value.integer.value; | ||
1210 | int change; | ||
1211 | |||
1212 | change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, | ||
1213 | 0x80, valp[0] & 0x80); | ||
1214 | change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, | ||
1215 | 0x80, valp[1] & 0x80); | ||
1216 | snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1217 | 0x80, valp[0] & 0x80); | ||
1218 | snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1219 | 0x80, valp[1] & 0x80); | ||
1220 | return change; | ||
1221 | } | ||
1222 | |||
1223 | static struct snd_kcontrol_new vaio_mixer[] = { | ||
1224 | { | ||
1225 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1226 | .name = "Master Playback Volume", | ||
1227 | .info = snd_hda_mixer_amp_volume_info, | ||
1228 | .get = snd_hda_mixer_amp_volume_get, | ||
1229 | .put = vaio_master_vol_put, | ||
1230 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1231 | }, | ||
1232 | { | ||
1233 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1234 | .name = "Master Playback Switch", | ||
1235 | .info = snd_hda_mixer_amp_switch_info, | ||
1236 | .get = snd_hda_mixer_amp_switch_get, | ||
1237 | .put = vaio_master_sw_put, | ||
1238 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1239 | }, | ||
1240 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
1241 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
1242 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
1243 | { | ||
1244 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1245 | .name = "Capture Source", | ||
1246 | .count = 1, | ||
1247 | .info = stac92xx_mux_enum_info, | ||
1248 | .get = stac92xx_mux_enum_get, | ||
1249 | .put = stac92xx_mux_enum_put, | ||
1250 | }, | ||
1251 | {} | ||
1252 | }; | ||
1253 | |||
1254 | static struct hda_codec_ops stac7661_patch_ops = { | ||
1255 | .build_controls = stac92xx_build_controls, | ||
1256 | .build_pcms = stac92xx_build_pcms, | ||
1257 | .init = stac92xx_init, | ||
1258 | .free = stac92xx_free, | ||
1259 | #ifdef CONFIG_PM | ||
1260 | .resume = stac92xx_resume, | ||
1261 | #endif | ||
1262 | }; | ||
1263 | |||
1264 | enum { STAC7661_VAIO }; | ||
1265 | |||
1266 | static struct hda_board_config stac7661_cfg_tbl[] = { | ||
1267 | { .modelname = "vaio", .config = STAC7661_VAIO }, | ||
1268 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, | ||
1269 | .config = STAC7661_VAIO }, | ||
1270 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, | ||
1271 | .config = STAC7661_VAIO }, | ||
1272 | {} | ||
1273 | }; | ||
1274 | |||
1275 | static int patch_stac7661(struct hda_codec *codec) | ||
1276 | { | ||
1277 | struct sigmatel_spec *spec; | ||
1278 | int board_config; | ||
1279 | |||
1280 | board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); | ||
1281 | if (board_config < 0) | ||
1282 | /* unknown config, let generic-parser do its job... */ | ||
1283 | return snd_hda_parse_generic_codec(codec); | ||
1284 | |||
1285 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1286 | if (spec == NULL) | ||
1287 | return -ENOMEM; | ||
1288 | |||
1289 | codec->spec = spec; | ||
1290 | switch (board_config) { | ||
1291 | case STAC7661_VAIO: | ||
1292 | spec->mixer = vaio_mixer; | ||
1293 | spec->init = vaio_init; | ||
1294 | spec->multiout.max_channels = 2; | ||
1295 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
1296 | spec->multiout.dac_nids = vaio_dacs; | ||
1297 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
1298 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
1299 | spec->adc_nids = vaio_adcs; | ||
1300 | spec->input_mux = &vaio_mux; | ||
1301 | spec->mux_nids = vaio_mux_nids; | ||
1302 | break; | ||
1303 | } | ||
1304 | |||
1305 | codec->patch_ops = stac7661_patch_ops; | ||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1309 | |||
1310 | /* | ||
1151 | * patch entries | 1311 | * patch entries |
1152 | */ | 1312 | */ |
1153 | struct hda_codec_preset snd_hda_preset_sigmatel[] = { | 1313 | struct hda_codec_preset snd_hda_preset_sigmatel[] = { |
@@ -1168,5 +1328,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
1168 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, | 1328 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, |
1169 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, | 1329 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, |
1170 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, | 1330 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, |
1331 | { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, | ||
1171 | {} /* terminator */ | 1332 | {} /* terminator */ |
1172 | }; | 1333 | }; |