aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-06-22 11:03:44 -0400
committerTakashi Iwai <tiwai@suse.de>2009-06-22 11:03:44 -0400
commit366890df46c2fd9492c04fe3a8775447b7b053e4 (patch)
tree57636b800255477ab3a51dcfaa59201c8c0ee38a /sound/pci
parent70052413e7b432ccef8ee82340fc01831a1a290c (diff)
parent29959a09cc1aabd2d5f4f03afc0305de6bd29248 (diff)
Merge branch 'topic/ctxfi' into for-linus
* topic/ctxfi: ALSA: ctxfi - Add PM support ALSA: ctxfi - Allow unknown PCI SSIDs
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/ctxfi/ctatc.c206
-rw-r--r--sound/pci/ctxfi/ctatc.h7
-rw-r--r--sound/pci/ctxfi/cthardware.h7
-rw-r--r--sound/pci/ctxfi/cthw20k1.c83
-rw-r--r--sound/pci/ctxfi/cthw20k2.c65
-rw-r--r--sound/pci/ctxfi/ctmixer.c92
-rw-r--r--sound/pci/ctxfi/ctmixer.h3
-rw-r--r--sound/pci/ctxfi/ctpcm.c4
-rw-r--r--sound/pci/ctxfi/xfi.c22
9 files changed, 376 insertions, 113 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index b0adc8094009..a49c76647307 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -46,8 +46,6 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
46 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X), 46 SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0031, "SB073x", CTSB073X),
47 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000, 47 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_CREATIVE, 0xf000, 0x6000,
48 "UAA", CTUAA), 48 "UAA", CTUAA),
49 SND_PCI_QUIRK_VENDOR(PCI_VENDOR_ID_CREATIVE,
50 "Unknown", CT20K1_UNKNOWN),
51 { } /* terminator */ 49 { } /* terminator */
52}; 50};
53 51
@@ -67,13 +65,16 @@ static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
67}; 65};
68 66
69static const char *ct_subsys_name[NUM_CTCARDS] = { 67static const char *ct_subsys_name[NUM_CTCARDS] = {
68 /* 20k1 models */
70 [CTSB055X] = "SB055x", 69 [CTSB055X] = "SB055x",
71 [CTSB073X] = "SB073x", 70 [CTSB073X] = "SB073x",
72 [CTSB0760] = "SB076x",
73 [CTUAA] = "UAA", 71 [CTUAA] = "UAA",
74 [CT20K1_UNKNOWN] = "Unknown", 72 [CT20K1_UNKNOWN] = "Unknown",
73 /* 20k2 models */
74 [CTSB0760] = "SB076x",
75 [CTHENDRIX] = "Hendrix", 75 [CTHENDRIX] = "Hendrix",
76 [CTSB0880] = "SB0880", 76 [CTSB0880] = "SB0880",
77 [CT20K2_UNKNOWN] = "Unknown",
77}; 78};
78 79
79static struct { 80static struct {
@@ -260,13 +261,8 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
260 int device = apcm->substream->pcm->device; 261 int device = apcm->substream->pcm->device;
261 unsigned int pitch; 262 unsigned int pitch;
262 263
263 if (NULL != apcm->src) {
264 /* Prepared pcm playback */
265 return 0;
266 }
267
268 /* first release old resources */ 264 /* first release old resources */
269 atc->pcm_release_resources(atc, apcm); 265 atc_pcm_release_resources(atc, apcm);
270 266
271 /* Get SRC resource */ 267 /* Get SRC resource */
272 desc.multi = apcm->substream->runtime->channels; 268 desc.multi = apcm->substream->runtime->channels;
@@ -660,10 +656,7 @@ static int atc_pcm_capture_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
660 unsigned int pitch; 656 unsigned int pitch;
661 int mix_base = 0, imp_base = 0; 657 int mix_base = 0, imp_base = 0;
662 658
663 if (NULL != apcm->src) { 659 atc_pcm_release_resources(atc, apcm);
664 /* Prepared pcm capture */
665 return 0;
666 }
667 660
668 /* Get needed resources. */ 661 /* Get needed resources. */
669 err = atc_pcm_capture_get_resources(atc, apcm); 662 err = atc_pcm_capture_get_resources(atc, apcm);
@@ -866,7 +859,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm)
866 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); 859 struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio);
867 unsigned int rate = apcm->substream->runtime->rate; 860 unsigned int rate = apcm->substream->runtime->rate;
868 unsigned int status; 861 unsigned int status;
869 int err; 862 int err = 0;
870 unsigned char iec958_con_fs; 863 unsigned char iec958_con_fs;
871 864
872 switch (rate) { 865 switch (rate) {
@@ -907,8 +900,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
907 int err; 900 int err;
908 int i; 901 int i;
909 902
910 if (NULL != apcm->src) 903 atc_pcm_release_resources(atc, apcm);
911 return 0;
912 904
913 /* Configure SPDIFOO and PLL to passthrough mode; 905 /* Configure SPDIFOO and PLL to passthrough mode;
914 * determine pll_rate. */ 906 * determine pll_rate. */
@@ -1115,32 +1107,20 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state)
1115 return err; 1107 return err;
1116} 1108}
1117 1109
1118static int ct_atc_destroy(struct ct_atc *atc) 1110static int atc_release_resources(struct ct_atc *atc)
1119{ 1111{
1120 struct daio_mgr *daio_mgr; 1112 int i;
1121 struct dao *dao; 1113 struct daio_mgr *daio_mgr = NULL;
1122 struct dai *dai; 1114 struct dao *dao = NULL;
1123 struct daio *daio; 1115 struct dai *dai = NULL;
1124 struct sum_mgr *sum_mgr; 1116 struct daio *daio = NULL;
1125 struct src_mgr *src_mgr; 1117 struct sum_mgr *sum_mgr = NULL;
1126 struct srcimp_mgr *srcimp_mgr; 1118 struct src_mgr *src_mgr = NULL;
1127 struct srcimp *srcimp; 1119 struct srcimp_mgr *srcimp_mgr = NULL;
1128 struct ct_mixer *mixer; 1120 struct srcimp *srcimp = NULL;
1129 int i = 0; 1121 struct ct_mixer *mixer = NULL;
1130 1122
1131 if (NULL == atc) 1123 /* disconnect internal mixer objects */
1132 return 0;
1133
1134 if (atc->timer) {
1135 ct_timer_free(atc->timer);
1136 atc->timer = NULL;
1137 }
1138
1139 /* Stop hardware and disable all interrupts */
1140 if (NULL != atc->hw)
1141 ((struct hw *)atc->hw)->card_stop(atc->hw);
1142
1143 /* Destroy internal mixer objects */
1144 if (NULL != atc->mixer) { 1124 if (NULL != atc->mixer) {
1145 mixer = atc->mixer; 1125 mixer = atc->mixer;
1146 mixer->set_input_left(mixer, MIX_LINE_IN, NULL); 1126 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
@@ -1149,7 +1129,6 @@ static int ct_atc_destroy(struct ct_atc *atc)
1149 mixer->set_input_right(mixer, MIX_MIC_IN, NULL); 1129 mixer->set_input_right(mixer, MIX_MIC_IN, NULL);
1150 mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL); 1130 mixer->set_input_left(mixer, MIX_SPDIF_IN, NULL);
1151 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); 1131 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
1152 ct_mixer_destroy(atc->mixer);
1153 } 1132 }
1154 1133
1155 if (NULL != atc->daios) { 1134 if (NULL != atc->daios) {
@@ -1167,6 +1146,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
1167 daio_mgr->put_daio(daio_mgr, daio); 1146 daio_mgr->put_daio(daio_mgr, daio);
1168 } 1147 }
1169 kfree(atc->daios); 1148 kfree(atc->daios);
1149 atc->daios = NULL;
1170 } 1150 }
1171 1151
1172 if (NULL != atc->pcm) { 1152 if (NULL != atc->pcm) {
@@ -1175,6 +1155,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
1175 sum_mgr->put_sum(sum_mgr, atc->pcm[i]); 1155 sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
1176 1156
1177 kfree(atc->pcm); 1157 kfree(atc->pcm);
1158 atc->pcm = NULL;
1178 } 1159 }
1179 1160
1180 if (NULL != atc->srcs) { 1161 if (NULL != atc->srcs) {
@@ -1183,6 +1164,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
1183 src_mgr->put_src(src_mgr, atc->srcs[i]); 1164 src_mgr->put_src(src_mgr, atc->srcs[i]);
1184 1165
1185 kfree(atc->srcs); 1166 kfree(atc->srcs);
1167 atc->srcs = NULL;
1186 } 1168 }
1187 1169
1188 if (NULL != atc->srcimps) { 1170 if (NULL != atc->srcimps) {
@@ -1193,8 +1175,30 @@ static int ct_atc_destroy(struct ct_atc *atc)
1193 srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]); 1175 srcimp_mgr->put_srcimp(srcimp_mgr, atc->srcimps[i]);
1194 } 1176 }
1195 kfree(atc->srcimps); 1177 kfree(atc->srcimps);
1178 atc->srcimps = NULL;
1179 }
1180
1181 return 0;
1182}
1183
1184static int ct_atc_destroy(struct ct_atc *atc)
1185{
1186 int i = 0;
1187
1188 if (NULL == atc)
1189 return 0;
1190
1191 if (atc->timer) {
1192 ct_timer_free(atc->timer);
1193 atc->timer = NULL;
1196 } 1194 }
1197 1195
1196 atc_release_resources(atc);
1197
1198 /* Destroy internal mixer objects */
1199 if (NULL != atc->mixer)
1200 ct_mixer_destroy(atc->mixer);
1201
1198 for (i = 0; i < NUM_RSCTYP; i++) { 1202 for (i = 0; i < NUM_RSCTYP; i++) {
1199 if ((NULL != rsc_mgr_funcs[i].destroy) && 1203 if ((NULL != rsc_mgr_funcs[i].destroy) &&
1200 (NULL != atc->rsc_mgrs[i])) 1204 (NULL != atc->rsc_mgrs[i]))
@@ -1240,9 +1244,21 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
1240 return -ENOENT; 1244 return -ENOENT;
1241 } 1245 }
1242 p = snd_pci_quirk_lookup(atc->pci, list); 1246 p = snd_pci_quirk_lookup(atc->pci, list);
1243 if (!p) 1247 if (p) {
1244 return -ENOENT; 1248 if (p->value < 0) {
1245 atc->model = p->value; 1249 printk(KERN_ERR "ctxfi: "
1250 "Device %04x:%04x is black-listed\n",
1251 atc->pci->subsystem_vendor,
1252 atc->pci->subsystem_device);
1253 return -ENOENT;
1254 }
1255 atc->model = p->value;
1256 } else {
1257 if (atc->chip_type == ATC20K1)
1258 atc->model = CT20K1_UNKNOWN;
1259 else
1260 atc->model = CT20K2_UNKNOWN;
1261 }
1246 atc->model_name = ct_subsys_name[atc->model]; 1262 atc->model_name = ct_subsys_name[atc->model];
1247 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n", 1263 snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
1248 atc->chip_name, atc->model_name, 1264 atc->chip_name, atc->model_name,
@@ -1310,7 +1326,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc)
1310 return 0; 1326 return 0;
1311} 1327}
1312 1328
1313static int __devinit atc_get_resources(struct ct_atc *atc) 1329static int atc_get_resources(struct ct_atc *atc)
1314{ 1330{
1315 struct daio_desc da_desc = {0}; 1331 struct daio_desc da_desc = {0};
1316 struct daio_mgr *daio_mgr; 1332 struct daio_mgr *daio_mgr;
@@ -1407,16 +1423,10 @@ static int __devinit atc_get_resources(struct ct_atc *atc)
1407 atc->n_pcm++; 1423 atc->n_pcm++;
1408 } 1424 }
1409 1425
1410 err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
1411 if (err) {
1412 printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
1413 return err;
1414 }
1415
1416 return 0; 1426 return 0;
1417} 1427}
1418 1428
1419static void __devinit 1429static void
1420atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai, 1430atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
1421 struct src **srcs, struct srcimp **srcimps) 1431 struct src **srcs, struct srcimp **srcimps)
1422{ 1432{
@@ -1455,7 +1465,7 @@ atc_connect_dai(struct src_mgr *src_mgr, struct dai *dai,
1455 src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */ 1465 src_mgr->commit_write(src_mgr); /* Synchronously enable SRCs */
1456} 1466}
1457 1467
1458static void __devinit atc_connect_resources(struct ct_atc *atc) 1468static void atc_connect_resources(struct ct_atc *atc)
1459{ 1469{
1460 struct dai *dai; 1470 struct dai *dai;
1461 struct dao *dao; 1471 struct dao *dao;
@@ -1501,6 +1511,84 @@ static void __devinit atc_connect_resources(struct ct_atc *atc)
1501 } 1511 }
1502} 1512}
1503 1513
1514#ifdef CONFIG_PM
1515static int atc_suspend(struct ct_atc *atc, pm_message_t state)
1516{
1517 int i;
1518 struct hw *hw = atc->hw;
1519
1520 snd_power_change_state(atc->card, SNDRV_CTL_POWER_D3hot);
1521
1522 for (i = FRONT; i < NUM_PCMS; i++) {
1523 if (!atc->pcms[i])
1524 continue;
1525
1526 snd_pcm_suspend_all(atc->pcms[i]);
1527 }
1528
1529 atc_release_resources(atc);
1530
1531 hw->suspend(hw, state);
1532
1533 return 0;
1534}
1535
1536static int atc_hw_resume(struct ct_atc *atc)
1537{
1538 struct hw *hw = atc->hw;
1539 struct card_conf info = {0};
1540
1541 /* Re-initialize card hardware. */
1542 info.rsr = atc->rsr;
1543 info.msr = atc->msr;
1544 info.vm_pgt_phys = atc_get_ptp_phys(atc, 0);
1545 return hw->resume(hw, &info);
1546}
1547
1548static int atc_resources_resume(struct ct_atc *atc)
1549{
1550 struct ct_mixer *mixer;
1551 int err = 0;
1552
1553 /* Get resources */
1554 err = atc_get_resources(atc);
1555 if (err < 0) {
1556 atc_release_resources(atc);
1557 return err;
1558 }
1559
1560 /* Build topology */
1561 atc_connect_resources(atc);
1562
1563 mixer = atc->mixer;
1564 mixer->resume(mixer);
1565
1566 return 0;
1567}
1568
1569static int atc_resume(struct ct_atc *atc)
1570{
1571 int err = 0;
1572
1573 /* Do hardware resume. */
1574 err = atc_hw_resume(atc);
1575 if (err < 0) {
1576 printk(KERN_ERR "ctxfi: pci_enable_device failed, "
1577 "disabling device\n");
1578 snd_card_disconnect(atc->card);
1579 return err;
1580 }
1581
1582 err = atc_resources_resume(atc);
1583 if (err < 0)
1584 return err;
1585
1586 snd_power_change_state(atc->card, SNDRV_CTL_POWER_D0);
1587
1588 return 0;
1589}
1590#endif
1591
1504static struct ct_atc atc_preset __devinitdata = { 1592static struct ct_atc atc_preset __devinitdata = {
1505 .map_audio_buffer = ct_map_audio_buffer, 1593 .map_audio_buffer = ct_map_audio_buffer,
1506 .unmap_audio_buffer = ct_unmap_audio_buffer, 1594 .unmap_audio_buffer = ct_unmap_audio_buffer,
@@ -1529,6 +1617,10 @@ static struct ct_atc atc_preset __devinitdata = {
1529 .spdif_out_set_status = atc_spdif_out_set_status, 1617 .spdif_out_set_status = atc_spdif_out_set_status,
1530 .spdif_out_passthru = atc_spdif_out_passthru, 1618 .spdif_out_passthru = atc_spdif_out_passthru,
1531 .have_digit_io_switch = atc_have_digit_io_switch, 1619 .have_digit_io_switch = atc_have_digit_io_switch,
1620#ifdef CONFIG_PM
1621 .suspend = atc_suspend,
1622 .resume = atc_resume,
1623#endif
1532}; 1624};
1533 1625
1534/** 1626/**
@@ -1587,6 +1679,12 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1587 if (err < 0) 1679 if (err < 0)
1588 goto error1; 1680 goto error1;
1589 1681
1682 err = ct_mixer_create(atc, (struct ct_mixer **)&atc->mixer);
1683 if (err) {
1684 printk(KERN_ERR "ctxfi: Failed to create mixer obj!!!\n");
1685 goto error1;
1686 }
1687
1590 /* Get resources */ 1688 /* Get resources */
1591 err = atc_get_resources(atc); 1689 err = atc_get_resources(atc);
1592 if (err < 0) 1690 if (err < 0)
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 9fe620ea5f3f..9fd8a5708943 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -136,6 +136,13 @@ struct ct_atc {
136 unsigned char n_pcm; 136 unsigned char n_pcm;
137 137
138 struct ct_timer *timer; 138 struct ct_timer *timer;
139
140#ifdef CONFIG_PM
141 int (*suspend)(struct ct_atc *atc, pm_message_t state);
142 int (*resume)(struct ct_atc *atc);
143#define NUM_PCMS (NUM_CTALSADEVS - 1)
144 struct snd_pcm *pcms[NUM_PCMS];
145#endif
139}; 146};
140 147
141 148
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index 4a8e04f090a4..af55405f5dec 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -30,13 +30,16 @@ enum CHIPTYP {
30enum CTCARDS { 30enum CTCARDS {
31 /* 20k1 models */ 31 /* 20k1 models */
32 CTSB055X, 32 CTSB055X,
33 CT20K1_MODEL_FIRST = CTSB055X,
33 CTSB073X, 34 CTSB073X,
34 CTUAA, 35 CTUAA,
35 CT20K1_UNKNOWN, 36 CT20K1_UNKNOWN,
36 /* 20k2 models */ 37 /* 20k2 models */
37 CTSB0760, 38 CTSB0760,
39 CT20K2_MODEL_FIRST = CTSB0760,
38 CTHENDRIX, 40 CTHENDRIX,
39 CTSB0880, 41 CTSB0880,
42 CT20K2_UNKNOWN,
40 NUM_CTCARDS /* This should always be the last */ 43 NUM_CTCARDS /* This should always be the last */
41}; 44};
42 45
@@ -61,6 +64,10 @@ struct hw {
61 int (*card_init)(struct hw *hw, struct card_conf *info); 64 int (*card_init)(struct hw *hw, struct card_conf *info);
62 int (*card_stop)(struct hw *hw); 65 int (*card_stop)(struct hw *hw);
63 int (*pll_init)(struct hw *hw, unsigned int rsr); 66 int (*pll_init)(struct hw *hw, unsigned int rsr);
67#ifdef CONFIG_PM
68 int (*suspend)(struct hw *hw, pm_message_t state);
69 int (*resume)(struct hw *hw, struct card_conf *info);
70#endif
64 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); 71 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
65 int (*select_adc_source)(struct hw *hw, enum ADCSRC source); 72 int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
66 int (*have_digit_io_switch)(struct hw *hw); 73 int (*have_digit_io_switch)(struct hw *hw);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index cb69d9ddfbe3..ad3e1d144464 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -1911,9 +1911,17 @@ static int hw_card_start(struct hw *hw)
1911 goto error1; 1911 goto error1;
1912 } 1912 }
1913 1913
1914 err = pci_request_regions(pci, "XFi"); 1914 if (!hw->io_base) {
1915 if (err < 0) 1915 err = pci_request_regions(pci, "XFi");
1916 goto error1; 1916 if (err < 0)
1917 goto error1;
1918
1919 if (hw->model == CTUAA)
1920 hw->io_base = pci_resource_start(pci, 5);
1921 else
1922 hw->io_base = pci_resource_start(pci, 0);
1923
1924 }
1917 1925
1918 /* Switch to X-Fi mode from UAA mode if neeeded */ 1926 /* Switch to X-Fi mode from UAA mode if neeeded */
1919 if (hw->model == CTUAA) { 1927 if (hw->model == CTUAA) {
@@ -1921,18 +1929,17 @@ static int hw_card_start(struct hw *hw)
1921 if (err) 1929 if (err)
1922 goto error2; 1930 goto error2;
1923 1931
1924 hw->io_base = pci_resource_start(pci, 5);
1925 } else {
1926 hw->io_base = pci_resource_start(pci, 0);
1927 } 1932 }
1928 1933
1929 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED, 1934 if (hw->irq < 0) {
1930 "ctxfi", hw); 1935 err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
1931 if (err < 0) { 1936 "ctxfi", hw);
1932 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq); 1937 if (err < 0) {
1933 goto error2; 1938 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1939 goto error2;
1940 }
1941 hw->irq = pci->irq;
1934 } 1942 }
1935 hw->irq = pci->irq;
1936 1943
1937 pci_set_master(pci); 1944 pci_set_master(pci);
1938 1945
@@ -1948,6 +1955,15 @@ error1:
1948 1955
1949static int hw_card_stop(struct hw *hw) 1956static int hw_card_stop(struct hw *hw)
1950{ 1957{
1958 unsigned int data;
1959
1960 /* disable transport bus master and queueing of request */
1961 hw_write_20kx(hw, TRNCTL, 0x00);
1962
1963 /* disable pll */
1964 data = hw_read_20kx(hw, PLLCTL);
1965 hw_write_20kx(hw, PLLCTL, (data & (~(0x0F<<12))));
1966
1951 /* TODO: Disable interrupt and so on... */ 1967 /* TODO: Disable interrupt and so on... */
1952 if (hw->irq >= 0) 1968 if (hw->irq >= 0)
1953 synchronize_irq(hw->irq); 1969 synchronize_irq(hw->irq);
@@ -1987,11 +2003,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
1987 struct trn_conf trn_info = {0}; 2003 struct trn_conf trn_info = {0};
1988 2004
1989 /* Get PCI io port base address and do Hendrix switch if needed. */ 2005 /* Get PCI io port base address and do Hendrix switch if needed. */
1990 if (!hw->io_base) { 2006 err = hw_card_start(hw);
1991 err = hw_card_start(hw); 2007 if (err)
1992 if (err) 2008 return err;
1993 return err;
1994 }
1995 2009
1996 /* PLL init */ 2010 /* PLL init */
1997 err = hw_pll_init(hw, info->rsr); 2011 err = hw_pll_init(hw, info->rsr);
@@ -2064,6 +2078,37 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2064 return 0; 2078 return 0;
2065} 2079}
2066 2080
2081#ifdef CONFIG_PM
2082static int hw_suspend(struct hw *hw, pm_message_t state)
2083{
2084 struct pci_dev *pci = hw->pci;
2085
2086 hw_card_stop(hw);
2087
2088 if (hw->model == CTUAA) {
2089 /* Switch to UAA config space. */
2090 pci_write_config_dword(pci, UAA_CFG_SPACE_FLAG, 0x0);
2091 }
2092
2093 pci_disable_device(pci);
2094 pci_save_state(pci);
2095 pci_set_power_state(pci, pci_choose_state(pci, state));
2096
2097 return 0;
2098}
2099
2100static int hw_resume(struct hw *hw, struct card_conf *info)
2101{
2102 struct pci_dev *pci = hw->pci;
2103
2104 pci_set_power_state(pci, PCI_D0);
2105 pci_restore_state(pci);
2106
2107 /* Re-initialize card hardware. */
2108 return hw_card_init(hw, info);
2109}
2110#endif
2111
2067static u32 hw_read_20kx(struct hw *hw, u32 reg) 2112static u32 hw_read_20kx(struct hw *hw, u32 reg)
2068{ 2113{
2069 u32 value; 2114 u32 value;
@@ -2128,6 +2173,10 @@ static struct hw ct20k1_preset __devinitdata = {
2128 .is_adc_source_selected = hw_is_adc_input_selected, 2173 .is_adc_source_selected = hw_is_adc_input_selected,
2129 .select_adc_source = hw_adc_input_select, 2174 .select_adc_source = hw_adc_input_select,
2130 .have_digit_io_switch = hw_have_digit_io_switch, 2175 .have_digit_io_switch = hw_have_digit_io_switch,
2176#ifdef CONFIG_PM
2177 .suspend = hw_suspend,
2178 .resume = hw_resume,
2179#endif
2131 2180
2132 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, 2181 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
2133 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, 2182 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 4493a51c6b01..dec46d04b041 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -1860,16 +1860,18 @@ static int hw_card_start(struct hw *hw)
1860 goto error1; 1860 goto error1;
1861 } 1861 }
1862 1862
1863 err = pci_request_regions(pci, "XFi"); 1863 if (!hw->io_base) {
1864 if (err < 0) 1864 err = pci_request_regions(pci, "XFi");
1865 goto error1; 1865 if (err < 0)
1866 goto error1;
1866 1867
1867 hw->io_base = pci_resource_start(hw->pci, 2); 1868 hw->io_base = pci_resource_start(hw->pci, 2);
1868 hw->mem_base = (unsigned long)ioremap(hw->io_base, 1869 hw->mem_base = (unsigned long)ioremap(hw->io_base,
1869 pci_resource_len(hw->pci, 2)); 1870 pci_resource_len(hw->pci, 2));
1870 if (NULL == (void *)hw->mem_base) { 1871 if (NULL == (void *)hw->mem_base) {
1871 err = -ENOENT; 1872 err = -ENOENT;
1872 goto error2; 1873 goto error2;
1874 }
1873 } 1875 }
1874 1876
1875 /* Switch to 20k2 mode from UAA mode. */ 1877 /* Switch to 20k2 mode from UAA mode. */
@@ -1901,6 +1903,15 @@ error1:
1901 1903
1902static int hw_card_stop(struct hw *hw) 1904static int hw_card_stop(struct hw *hw)
1903{ 1905{
1906 unsigned int data;
1907
1908 /* disable transport bus master and queueing of request */
1909 hw_write_20kx(hw, TRANSPORT_CTL, 0x00);
1910
1911 /* disable pll */
1912 data = hw_read_20kx(hw, PLL_ENB);
1913 hw_write_20kx(hw, PLL_ENB, (data & (~0x07)));
1914
1904 /* TODO: Disable interrupt and so on... */ 1915 /* TODO: Disable interrupt and so on... */
1905 return 0; 1916 return 0;
1906} 1917}
@@ -1939,11 +1950,9 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
1939 1950
1940 /* Get PCI io port/memory base address and 1951 /* Get PCI io port/memory base address and
1941 * do 20kx core switch if needed. */ 1952 * do 20kx core switch if needed. */
1942 if (!hw->io_base) { 1953 err = hw_card_start(hw);
1943 err = hw_card_start(hw); 1954 if (err)
1944 if (err) 1955 return err;
1945 return err;
1946 }
1947 1956
1948 /* PLL init */ 1957 /* PLL init */
1949 err = hw_pll_init(hw, info->rsr); 1958 err = hw_pll_init(hw, info->rsr);
@@ -2006,6 +2015,32 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2006 return 0; 2015 return 0;
2007} 2016}
2008 2017
2018#ifdef CONFIG_PM
2019static int hw_suspend(struct hw *hw, pm_message_t state)
2020{
2021 struct pci_dev *pci = hw->pci;
2022
2023 hw_card_stop(hw);
2024
2025 pci_disable_device(pci);
2026 pci_save_state(pci);
2027 pci_set_power_state(pci, pci_choose_state(pci, state));
2028
2029 return 0;
2030}
2031
2032static int hw_resume(struct hw *hw, struct card_conf *info)
2033{
2034 struct pci_dev *pci = hw->pci;
2035
2036 pci_set_power_state(pci, PCI_D0);
2037 pci_restore_state(pci);
2038
2039 /* Re-initialize card hardware. */
2040 return hw_card_init(hw, info);
2041}
2042#endif
2043
2009static u32 hw_read_20kx(struct hw *hw, u32 reg) 2044static u32 hw_read_20kx(struct hw *hw, u32 reg)
2010{ 2045{
2011 return readl((void *)(hw->mem_base + reg)); 2046 return readl((void *)(hw->mem_base + reg));
@@ -2025,6 +2060,10 @@ static struct hw ct20k2_preset __devinitdata = {
2025 .is_adc_source_selected = hw_is_adc_input_selected, 2060 .is_adc_source_selected = hw_is_adc_input_selected,
2026 .select_adc_source = hw_adc_input_select, 2061 .select_adc_source = hw_adc_input_select,
2027 .have_digit_io_switch = hw_have_digit_io_switch, 2062 .have_digit_io_switch = hw_have_digit_io_switch,
2063#ifdef CONFIG_PM
2064 .suspend = hw_suspend,
2065 .resume = hw_resume,
2066#endif
2028 2067
2029 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk, 2068 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
2030 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk, 2069 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index 666722d9de41..f26d7cd9db9f 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -462,6 +462,43 @@ do_digit_io_switch(struct ct_atc *atc, int state)
462 return; 462 return;
463} 463}
464 464
465static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
466{
467 struct ct_mixer *mixer = atc->mixer;
468
469 /* Do changes in mixer. */
470 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
471 if (state) {
472 ct_mixer_recording_select(mixer,
473 get_amixer_index(type));
474 } else {
475 ct_mixer_recording_unselect(mixer,
476 get_amixer_index(type));
477 }
478 }
479 /* Do changes out of mixer. */
480 if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
481 do_line_mic_switch(atc, type);
482 else if (MIXER_WAVEF_P_S == type)
483 atc->line_front_unmute(atc, state);
484 else if (MIXER_WAVES_P_S == type)
485 atc->line_surround_unmute(atc, state);
486 else if (MIXER_WAVEC_P_S == type)
487 atc->line_clfe_unmute(atc, state);
488 else if (MIXER_WAVER_P_S == type)
489 atc->line_rear_unmute(atc, state);
490 else if (MIXER_LINEIN_P_S == type)
491 atc->line_in_unmute(atc, state);
492 else if (MIXER_SPDIFO_P_S == type)
493 atc->spdif_out_unmute(atc, state);
494 else if (MIXER_SPDIFI_P_S == type)
495 atc->spdif_in_unmute(atc, state);
496 else if (MIXER_DIGITAL_IO_S == type)
497 do_digit_io_switch(atc, state);
498
499 return;
500}
501
465static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol, 502static int ct_alsa_mix_switch_info(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_info *uinfo) 503 struct snd_ctl_elem_info *uinfo)
467{ 504{
@@ -498,35 +535,7 @@ static int ct_alsa_mix_switch_put(struct snd_kcontrol *kcontrol,
498 return 0; 535 return 0;
499 536
500 set_switch_state(mixer, type, state); 537 set_switch_state(mixer, type, state);
501 /* Do changes in mixer. */ 538 do_switch(atc, type, state);
502 if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
503 if (state) {
504 ct_mixer_recording_select(mixer,
505 get_amixer_index(type));
506 } else {
507 ct_mixer_recording_unselect(mixer,
508 get_amixer_index(type));
509 }
510 }
511 /* Do changes out of mixer. */
512 if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
513 do_line_mic_switch(atc, type);
514 else if (MIXER_WAVEF_P_S == type)
515 atc->line_front_unmute(atc, state);
516 else if (MIXER_WAVES_P_S == type)
517 atc->line_surround_unmute(atc, state);
518 else if (MIXER_WAVEC_P_S == type)
519 atc->line_clfe_unmute(atc, state);
520 else if (MIXER_WAVER_P_S == type)
521 atc->line_rear_unmute(atc, state);
522 else if (MIXER_LINEIN_P_S == type)
523 atc->line_in_unmute(atc, state);
524 else if (MIXER_SPDIFO_P_S == type)
525 atc->spdif_out_unmute(atc, state);
526 else if (MIXER_SPDIFI_P_S == type)
527 atc->spdif_in_unmute(atc, state);
528 else if (MIXER_DIGITAL_IO_S == type)
529 do_digit_io_switch(atc, state);
530 539
531 return 1; 540 return 1;
532} 541}
@@ -1039,6 +1048,28 @@ mixer_set_input_right(struct ct_mixer *mixer,
1039 return 0; 1048 return 0;
1040} 1049}
1041 1050
1051#ifdef CONFIG_PM
1052static int mixer_resume(struct ct_mixer *mixer)
1053{
1054 int i, state;
1055 struct amixer *amixer;
1056
1057 /* resume topology and volume gain. */
1058 for (i = 0; i < NUM_CT_AMIXERS*CHN_NUM; i++) {
1059 amixer = mixer->amixers[i];
1060 amixer->ops->commit_write(amixer);
1061 }
1062
1063 /* resume switch state. */
1064 for (i = SWH_MIXER_START; i <= SWH_MIXER_END; i++) {
1065 state = get_switch_state(mixer, i);
1066 do_switch(mixer->atc, i, state);
1067 }
1068
1069 return 0;
1070}
1071#endif
1072
1042int ct_mixer_destroy(struct ct_mixer *mixer) 1073int ct_mixer_destroy(struct ct_mixer *mixer)
1043{ 1074{
1044 struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM]; 1075 struct sum_mgr *sum_mgr = (struct sum_mgr *)mixer->atc->rsc_mgrs[SUM];
@@ -1087,6 +1118,9 @@ int ct_mixer_create(struct ct_atc *atc, struct ct_mixer **rmixer)
1087 mixer->get_output_ports = mixer_get_output_ports; 1118 mixer->get_output_ports = mixer_get_output_ports;
1088 mixer->set_input_left = mixer_set_input_left; 1119 mixer->set_input_left = mixer_set_input_left;
1089 mixer->set_input_right = mixer_set_input_right; 1120 mixer->set_input_right = mixer_set_input_right;
1121#ifdef CONFIG_PM
1122 mixer->resume = mixer_resume;
1123#endif
1090 1124
1091 /* Allocate chip resources for mixer obj */ 1125 /* Allocate chip resources for mixer obj */
1092 err = ct_mixer_get_resources(mixer); 1126 err = ct_mixer_get_resources(mixer);
diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h
index e2d96ebde746..b009e989e77d 100644
--- a/sound/pci/ctxfi/ctmixer.h
+++ b/sound/pci/ctxfi/ctmixer.h
@@ -56,6 +56,9 @@ struct ct_mixer {
56 enum MIXER_PORT_T type, struct rsc *rsc); 56 enum MIXER_PORT_T type, struct rsc *rsc);
57 int (*set_input_right)(struct ct_mixer *mixer, 57 int (*set_input_right)(struct ct_mixer *mixer,
58 enum MIXER_PORT_T type, struct rsc *rsc); 58 enum MIXER_PORT_T type, struct rsc *rsc);
59#ifdef CONFIG_PM
60 int (*resume)(struct ct_mixer *mixer);
61#endif
59}; 62};
60 63
61int ct_alsa_mix_create(struct ct_atc *atc, 64int ct_alsa_mix_create(struct ct_atc *atc,
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 9e5c0c4da726..60ea23180acb 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -422,5 +422,9 @@ int ct_alsa_pcm_create(struct ct_atc *atc,
422 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 422 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
423 snd_dma_pci_data(atc->pci), 128*1024, 128*1024); 423 snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
424 424
425#ifdef CONFIG_PM
426 atc->pcms[device] = pcm;
427#endif
428
425 return 0; 429 return 0;
426} 430}
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 2d3dd89af151..76541748e7bc 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -121,11 +121,33 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
121 pci_set_drvdata(pci, NULL); 121 pci_set_drvdata(pci, NULL);
122} 122}
123 123
124#ifdef CONFIG_PM
125static int ct_card_suspend(struct pci_dev *pci, pm_message_t state)
126{
127 struct snd_card *card = pci_get_drvdata(pci);
128 struct ct_atc *atc = card->private_data;
129
130 return atc->suspend(atc, state);
131}
132
133static int ct_card_resume(struct pci_dev *pci)
134{
135 struct snd_card *card = pci_get_drvdata(pci);
136 struct ct_atc *atc = card->private_data;
137
138 return atc->resume(atc);
139}
140#endif
141
124static struct pci_driver ct_driver = { 142static struct pci_driver ct_driver = {
125 .name = "SB-XFi", 143 .name = "SB-XFi",
126 .id_table = ct_pci_dev_ids, 144 .id_table = ct_pci_dev_ids,
127 .probe = ct_card_probe, 145 .probe = ct_card_probe,
128 .remove = __devexit_p(ct_card_remove), 146 .remove = __devexit_p(ct_card_remove),
147#ifdef CONFIG_PM
148 .suspend = ct_card_suspend,
149 .resume = ct_card_resume,
150#endif
129}; 151};
130 152
131static int __init ct_card_init(void) 153static int __init ct_card_init(void)