Deleted Added
full compact
csapcm.c (139749) csapcm.c (147626)
1/*-
2 * Copyright (c) 1999 Seigo Tanimura
3 * All rights reserved.
4 *
5 * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in
6 * cwcealdr1.zip, the sample sources by Crystal Semiconductor.
7 * Copyright (c) 1996-1998 Crystal Semiconductor Corp.
8 *

--- 24 unchanged lines hidden (view full) ---

33#include <dev/sound/pcm/ac97.h>
34#include <dev/sound/chip.h>
35#include <dev/sound/pci/csareg.h>
36#include <dev/sound/pci/csavar.h>
37
38#include <dev/pci/pcireg.h>
39#include <dev/pci/pcivar.h>
40
1/*-
2 * Copyright (c) 1999 Seigo Tanimura
3 * All rights reserved.
4 *
5 * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in
6 * cwcealdr1.zip, the sample sources by Crystal Semiconductor.
7 * Copyright (c) 1996-1998 Crystal Semiconductor Corp.
8 *

--- 24 unchanged lines hidden (view full) ---

33#include <dev/sound/pcm/ac97.h>
34#include <dev/sound/chip.h>
35#include <dev/sound/pci/csareg.h>
36#include <dev/sound/pci/csavar.h>
37
38#include <dev/pci/pcireg.h>
39#include <dev/pci/pcivar.h>
40
41SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/csapcm.c 139749 2005-01-06 01:43:34Z imp $");
41SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/csapcm.c 147626 2005-06-27 07:43:57Z glebius $");
42
43/* Buffer size on dma transfer. Fixed for CS416x. */
44#define CS461x_BUFFSIZE (4 * 1024)
45
46#define GOF_PER_SEC 200
47
48/* device private data */
49struct csa_info;

--- 15 unchanged lines hidden (view full) ---

65 struct csa_card *card;
66
67 int active;
68 /* Contents of board's registers */
69 u_long pfie;
70 u_long pctl;
71 u_long cctl;
72 struct csa_chinfo pch, rch;
42
43/* Buffer size on dma transfer. Fixed for CS416x. */
44#define CS461x_BUFFSIZE (4 * 1024)
45
46#define GOF_PER_SEC 200
47
48/* device private data */
49struct csa_info;

--- 15 unchanged lines hidden (view full) ---

65 struct csa_card *card;
66
67 int active;
68 /* Contents of board's registers */
69 u_long pfie;
70 u_long pctl;
71 u_long cctl;
72 struct csa_chinfo pch, rch;
73 u_int32_t ac97[CS461x_AC97_NUMBER_RESTORE_REGS];
74 u_int32_t ac97_powerdown;
75 u_int32_t ac97_general_purpose;
73};
74
75/* -------------------------------------------------------------------- */
76
77/* prototypes */
78static int csa_init(struct csa_info *);
79static void csa_intr(void *);
80static void csa_setplaysamplerate(csa_res *resp, u_long ulInRate);
81static void csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate);
82static void csa_startplaydma(struct csa_info *csa);
83static void csa_startcapturedma(struct csa_info *csa);
84static void csa_stopplaydma(struct csa_info *csa);
85static void csa_stopcapturedma(struct csa_info *csa);
86static int csa_startdsp(csa_res *resp);
76};
77
78/* -------------------------------------------------------------------- */
79
80/* prototypes */
81static int csa_init(struct csa_info *);
82static void csa_intr(void *);
83static void csa_setplaysamplerate(csa_res *resp, u_long ulInRate);
84static void csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate);
85static void csa_startplaydma(struct csa_info *csa);
86static void csa_startcapturedma(struct csa_info *csa);
87static void csa_stopplaydma(struct csa_info *csa);
88static void csa_stopcapturedma(struct csa_info *csa);
89static int csa_startdsp(csa_res *resp);
90static int csa_stopdsp(csa_res *resp);
87static int csa_allocres(struct csa_info *scp, device_t dev);
88static void csa_releaseres(struct csa_info *scp, device_t dev);
91static int csa_allocres(struct csa_info *scp, device_t dev);
92static void csa_releaseres(struct csa_info *scp, device_t dev);
93static void csa_ac97_suspend(struct csa_info *csa);
94static void csa_ac97_resume(struct csa_info *csa);
89
90static u_int32_t csa_playfmt[] = {
91 AFMT_U8,
92 AFMT_STEREO | AFMT_U8,
93 AFMT_S8,
94 AFMT_STEREO | AFMT_S8,
95 AFMT_S16_LE,
96 AFMT_STEREO | AFMT_S16_LE,

--- 10 unchanged lines hidden (view full) ---

107};
108static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
109
110/* -------------------------------------------------------------------- */
111
112static int
113csa_active(struct csa_info *csa, int run)
114{
95
96static u_int32_t csa_playfmt[] = {
97 AFMT_U8,
98 AFMT_STEREO | AFMT_U8,
99 AFMT_S8,
100 AFMT_STEREO | AFMT_S8,
101 AFMT_S16_LE,
102 AFMT_STEREO | AFMT_S16_LE,

--- 10 unchanged lines hidden (view full) ---

113};
114static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
115
116/* -------------------------------------------------------------------- */
117
118static int
119csa_active(struct csa_info *csa, int run)
120{
115 int old, go;
121 int old;
116
117 old = csa->active;
118 csa->active += run;
119
122
123 old = csa->active;
124 csa->active += run;
125
120 if ((csa->active == 0 && old == 1) || (csa->active == 1 && old == 0)) {
121 go = csa->active;
122 if (csa->card->active)
123 return csa->card->active(go);
124 }
126 if ((csa->active > 1) || (csa->active < -1))
127 csa->active = 0;
128 if (csa->card->active)
129 return (csa->card->active(!(csa->active && old)));
130
125 return 0;
126}
127
128/* -------------------------------------------------------------------- */
129/* ac97 codec */
130
131static int
132csa_rdcd(kobj_t obj, void *devinfo, int regno)

--- 317 unchanged lines hidden (view full) ---

450 */
451 if((ul & SPCR_RUNFR) != 0)
452 return (EAGAIN);
453
454 return (0);
455}
456
457static int
131 return 0;
132}
133
134/* -------------------------------------------------------------------- */
135/* ac97 codec */
136
137static int
138csa_rdcd(kobj_t obj, void *devinfo, int regno)

--- 317 unchanged lines hidden (view full) ---

456 */
457 if((ul & SPCR_RUNFR) != 0)
458 return (EAGAIN);
459
460 return (0);
461}
462
463static int
464csa_stopdsp(csa_res *resp)
465{
466 /*
467 * Turn off the run, run at frame, and DMA enable bits in
468 * the local copy of the SP control register.
469 */
470 csa_writemem(resp, BA1_SPCR, 0);
471
472 return (0);
473}
474
475static int
458csa_setupchan(struct csa_chinfo *ch)
459{
460 struct csa_info *csa = ch->parent;
461 csa_res *resp = &csa->res;
462 u_long pdtc, tmp;
463
464 if (ch->dir == PCMDIR_PLAY) {
465 /* direction */

--- 362 unchanged lines hidden (view full) ---

828 return r;
829
830 csa = pcm_getdevinfo(dev);
831 csa_releaseres(csa, dev);
832
833 return 0;
834}
835
476csa_setupchan(struct csa_chinfo *ch)
477{
478 struct csa_info *csa = ch->parent;
479 csa_res *resp = &csa->res;
480 u_long pdtc, tmp;
481
482 if (ch->dir == PCMDIR_PLAY) {
483 /* direction */

--- 362 unchanged lines hidden (view full) ---

846 return r;
847
848 csa = pcm_getdevinfo(dev);
849 csa_releaseres(csa, dev);
850
851 return 0;
852}
853
854static void
855csa_ac97_suspend(struct csa_info *csa)
856{
857 int count, i;
858 uint32_t tmp;
859
860 for (count = 0x2, i=0;
861 (count <= CS461x_AC97_HIGHESTREGTORESTORE) &&
862 (i < CS461x_AC97_NUMBER_RESTORE_REGS);
863 count += 2, i++)
864 csa_readcodec(&csa->res, BA0_AC97_RESET + count, &csa->ac97[i]);
865
866 /* mute the outputs */
867 csa_writecodec(&csa->res, BA0_AC97_MASTER_VOLUME, 0x8000);
868 csa_writecodec(&csa->res, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
869 csa_writecodec(&csa->res, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
870 csa_writecodec(&csa->res, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
871 /* save the registers that cause pops */
872 csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &csa->ac97_powerdown);
873 csa_readcodec(&csa->res, BA0_AC97_GENERAL_PURPOSE,
874 &csa->ac97_general_purpose);
875
876 /*
877 * And power down everything on the AC97 codec. Well, for now,
878 * only power down the DAC/ADC and MIXER VREFON components.
879 * trouble with removing VREF.
880 */
881
882 /* MIXVON */
883 csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
884 csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
885 tmp | CS_AC97_POWER_CONTROL_MIXVON);
886 /* ADC */
887 csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
888 csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
889 tmp | CS_AC97_POWER_CONTROL_ADC);
890 /* DAC */
891 csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
892 csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
893 tmp | CS_AC97_POWER_CONTROL_DAC);
894}
895
896static void
897csa_ac97_resume(struct csa_info *csa)
898{
899 int count, i;
900
901 /*
902 * First, we restore the state of the general purpose register. This
903 * contains the mic select (mic1 or mic2) and if we restore this after
904 * we restore the mic volume/boost state and mic2 was selected at
905 * suspend time, we will end up with a brief period of time where mic1
906 * is selected with the volume/boost settings for mic2, causing
907 * acoustic feedback. So we restore the general purpose register
908 * first, thereby getting the correct mic selected before we restore
909 * the mic volume/boost.
910 */
911 csa_writecodec(&csa->res, BA0_AC97_GENERAL_PURPOSE,
912 csa->ac97_general_purpose);
913 /*
914 * Now, while the outputs are still muted, restore the state of power
915 * on the AC97 part.
916 */
917 csa_writecodec(&csa->res, BA0_AC97_POWERDOWN, csa->ac97_powerdown);
918 /*
919 * Restore just the first set of registers, from register number
920 * 0x02 to the register number that ulHighestRegToRestore specifies.
921 */
922 for (count = 0x2, i=0;
923 (count <= CS461x_AC97_HIGHESTREGTORESTORE) &&
924 (i < CS461x_AC97_NUMBER_RESTORE_REGS);
925 count += 2, i++)
926 csa_writecodec(&csa->res, BA0_AC97_RESET + count, csa->ac97[i]);
927}
928
929static int
930pcmcsa_suspend(device_t dev)
931{
932 struct csa_info *csa;
933 csa_res *resp;
934
935 csa = pcm_getdevinfo(dev);
936 resp = &csa->res;
937
938 csa_active(csa, 1);
939
940 /* playback interrupt disable */
941 csa_writemem(resp, BA1_PFIE,
942 (csa_readmem(resp, BA1_PFIE) & ~0x0000f03f) | 0x00000010);
943 /* capture interrupt disable */
944 csa_writemem(resp, BA1_CIE,
945 (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000011);
946 csa_stopplaydma(csa);
947 csa_stopcapturedma(csa);
948
949 csa_ac97_suspend(csa);
950
951 csa_resetdsp(resp);
952
953 csa_stopdsp(resp);
954 /*
955 * Power down the DAC and ADC. For now leave the other areas on.
956 */
957 csa_writecodec(&csa->res, BA0_AC97_POWERDOWN, 0x300);
958 /*
959 * Power down the PLL.
960 */
961 csa_writemem(resp, BA0_CLKCR1, 0);
962 /*
963 * Turn off the Processor by turning off the software clock
964 * enable flag in the clock control register.
965 */
966 csa_writemem(resp, BA0_CLKCR1,
967 csa_readmem(resp, BA0_CLKCR1) & ~CLKCR1_SWCE);
968
969 csa_active(csa, -1);
970
971 return 0;
972}
973
974static int
975pcmcsa_resume(device_t dev)
976{
977 struct csa_info *csa;
978 csa_res *resp;
979
980 csa = pcm_getdevinfo(dev);
981 resp = &csa->res;
982
983 csa_active(csa, 1);
984
985 /* cs_hardware_init */
986 csa_stopplaydma(csa);
987 csa_stopcapturedma(csa);
988 csa_ac97_resume(csa);
989 if (csa_startdsp(resp))
990 return (ENXIO);
991 /* Enable interrupts on the part. */
992 if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0)
993 csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM);
994 /* playback interrupt enable */
995 csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f);
996 /* capture interrupt enable */
997 csa_writemem(resp, BA1_CIE,
998 (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
999 /* cs_restart_part */
1000 csa_setupchan(&csa->pch);
1001 csa_startplaydma(csa);
1002 csa_setupchan(&csa->rch);
1003 csa_startcapturedma(csa);
1004
1005 csa_active(csa, -1);
1006
1007 return 0;
1008}
1009
836static device_method_t pcmcsa_methods[] = {
837 /* Device interface */
838 DEVMETHOD(device_probe , pcmcsa_probe ),
839 DEVMETHOD(device_attach, pcmcsa_attach),
840 DEVMETHOD(device_detach, pcmcsa_detach),
1010static device_method_t pcmcsa_methods[] = {
1011 /* Device interface */
1012 DEVMETHOD(device_probe , pcmcsa_probe ),
1013 DEVMETHOD(device_attach, pcmcsa_attach),
1014 DEVMETHOD(device_detach, pcmcsa_detach),
1015 DEVMETHOD(device_suspend, pcmcsa_suspend),
1016 DEVMETHOD(device_resume, pcmcsa_resume),
841
842 { 0, 0 },
843};
844
845static driver_t pcmcsa_driver = {
846 "pcm",
847 pcmcsa_methods,
848 PCM_SOFTC_SIZE,
849};
850
851DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0);
852MODULE_DEPEND(snd_csapcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
853MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1);
854MODULE_VERSION(snd_csapcm, 1);
1017
1018 { 0, 0 },
1019};
1020
1021static driver_t pcmcsa_driver = {
1022 "pcm",
1023 pcmcsa_methods,
1024 PCM_SOFTC_SIZE,
1025};
1026
1027DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0);
1028MODULE_DEPEND(snd_csapcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1029MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1);
1030MODULE_VERSION(snd_csapcm, 1);