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); |