* [PATCH - ASIHPI 1/8] Common init files for HPI @ 2008-06-05 4:06 linux 2008-06-05 4:06 ` [PATCH - ASIHPI 2/8] Fix sampleclock source get. Fix volume control dB range linux 2008-06-05 4:34 ` [PATCH - ASIHPI 1/8] Common init files for HPI Eliot Blennerhassett 0 siblings, 2 replies; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/hpioctl.c b/pci/asihpi/hpioctl.c new file mode 100644 index 0000000..5192db3 --- /dev/null +++ b/pci/asihpi/hpioctl.c @@ -0,0 +1,440 @@ +/******************************************************************************* + + AudioScience HPI driver + Copyright (C) 1997-2003 AudioScience Inc. <support@audioscience.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Common Linux HPI ioctl and module probe/remove functions +*******************************************************************************/ +#define SOURCEFILE_NAME "hpioctl.c" + +#include "hpi.h" +#include "hpidebug.h" +#include "hpimsgx.h" +#include "hpioctl.h" + +#include <linux/fs.h> +#include <linux/slab.h> +#include <linux/moduleparam.h> +#include <asm/uaccess.h> +#include <linux/stringify.h> + +#ifndef HPIMOD_DEFAULT_BUF_SIZE +# define HPIMOD_DEFAULT_BUF_SIZE 192000 +#endif + +#ifdef MODULE_FIRMWARE +MODULE_FIRMWARE("asihpi/dsp5000.bin"); +MODULE_FIRMWARE("asihpi/dsp6200.bin"); +MODULE_FIRMWARE("asihpi/dsp6205.bin"); +MODULE_FIRMWARE("asihpi/dsp6400.bin"); +MODULE_FIRMWARE("asihpi/dsp6600.bin"); +MODULE_FIRMWARE("asihpi/dsp8700.bin"); +MODULE_FIRMWARE("asihpi/dsp8900.bin"); +#endif + +static int bufsize = HPIMOD_DEFAULT_BUF_SIZE; +module_param(bufsize, int, + S_IRUGO +); +/* Allow the debug level to be changed after module load. + E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel +*/ +module_param(hpiDebugLevel, int, + S_IRUGO | S_IWUSR +); + +/* List of adapters found */ +static struct hpi_adapter adapters[HPI_MAX_ADAPTERS]; + +/* Wrapper function to HPI_Message to enable dumping of the + message and response types. +*/ +static void HPI_MessageF( + struct hpi_message *phm, + struct hpi_response *phr, + struct file *file +) +{ + int nAdapter = phm->wAdapterIndex; + + if ((nAdapter >= HPI_MAX_ADAPTERS || nAdapter < 0) && + (phm->wObject != HPI_OBJ_SUBSYSTEM)) + phr->wError = HPI_ERROR_INVALID_OBJ_INDEX; + else + HPI_MessageEx(phm, phr, file); +} + +/* This is called from hpifunc.c functions, called by ALSA + * (or other kernel process) In this case there is no file descriptor + * available for the message cache code + */ +void HPI_Message( + struct hpi_message *phm, + struct hpi_response *phr +) +{ + HPI_MessageF(phm, phr, HOWNER_KERNEL); +} + +EXPORT_SYMBOL(HPI_Message); +/* export HPI_Message for radio-asihpi */ + +int asihpi_hpi_release( + struct file *file +) +{ + struct hpi_message hm; + struct hpi_response hr; + +/* HPI_DEBUG_LOG(INFO,"hpi_release file %p, pid %d\n", file, current->pid); */ + /* close the subsystem just in case the application forgot to. */ + HPI_InitMessage(&hm, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE); + HPI_MessageEx(&hm, &hr, file); + return 0; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 11) +long asihpi_hpi_ioctl( + struct file *file, + unsigned int cmd, + unsigned long arg +) +#else +int asihpi_hpi_ioctl( + struct inode *inode, + struct file *file, + unsigned int cmd, + unsigned long arg +) +#endif +{ + struct hpi_ioctl_linux __user *phpi_ioctl_data; + void __user *phm; + void __user *phr; + struct hpi_message hm; + struct hpi_response hr; + u32 uncopied_bytes; + struct hpi_adapter *pa; + + if (cmd != HPI_IOCTL_LINUX) + return -EINVAL; + + phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg; + + /* Read the message and response pointers from user space. */ + get_user(phm, &phpi_ioctl_data->phm); + get_user(phr, &phpi_ioctl_data->phr); + + /* Now read the message size and data from user space. */ + /* get_user(hm.wSize, (u16 __user *)phm); */ + uncopied_bytes = copy_from_user(&hm, phm, sizeof(hm)); + if (uncopied_bytes) + return -EFAULT; + + pa = &adapters[hm.wAdapterIndex]; + + if ((hm.wAdapterIndex > HPI_MAX_ADAPTERS) || (!pa->type)) { + HPI_InitResponse(&hr, HPI_OBJ_ADAPTER, HPI_ADAPTER_OPEN, + HPI_ERROR_BAD_ADAPTER_NUMBER); + + uncopied_bytes = copy_to_user(phr, &hr, sizeof(hr)); + if (uncopied_bytes) + return -EFAULT; + return 0; + } + + hr.wSize = 0; + /* Response filled either copy from cache, or by HPI_Message() */ + { + /* Dig out any pointers embedded in the message. */ + u16 __user *ptr = NULL; + u32 size = 0; + + /* -1=no data 0=read from user mem, 1=write to user mem */ + int wrflag = -1; + u32 nAdapter = hm.wAdapterIndex; + switch (hm.wFunction) { + case HPI_SUBSYS_CREATE_ADAPTER: + case HPI_SUBSYS_DELETE_ADAPTER: + /* Application must not use these functions! */ + hr.wSize = sizeof(struct hpi_response_header); + hr.wError = HPI_ERROR_INVALID_OPERATION; + hr.wFunction = hm.wFunction; + uncopied_bytes = copy_to_user(phr, &hr, hr.wSize); + if (uncopied_bytes) + return -EFAULT; + return 0; + case HPI_OSTREAM_WRITE: + case HPI_ISTREAM_READ: + /* Yes, sparse, this is correct. */ + ptr = (u16 __user *)hm.u.d.u.Data.pbData; + size = hm.u.d.u.Data.dwDataSize; + + hm.u.d.u.Data.pbData = pa->pBuffer; + /* + if (size > bufsize) { + size = bufsize; + hm.u.d.u.Data.dwDataSize = size; + } + */ + + if (hm.wFunction == HPI_ISTREAM_READ) + /* from card, WRITE to user mem */ + wrflag = 1; + else + wrflag = 0; + break; + + default: + break; + } + + if (mutex_lock_interruptible(&adapters[nAdapter].mutex)) + return -EINTR; + + if (wrflag == 0) { + if (size > bufsize) { + mutex_unlock(&adapters[nAdapter].mutex); + HPI_DEBUG_LOG(ERROR, + "Requested transfer of %d " + "bytes, max buffer size " + "is %d bytes.\n", size, bufsize); + return -EINVAL; + } + + uncopied_bytes = + copy_from_user(pa->pBuffer, ptr, size); + if (uncopied_bytes) + HPI_DEBUG_LOG(WARNING, + "Missed %d of %d " + "bytes from user\n", + uncopied_bytes, size); + } + + HPI_MessageF(&hm, &hr, file); + + if (wrflag == 1) { + if (size > bufsize) { + mutex_unlock(&adapters[nAdapter].mutex); + HPI_DEBUG_LOG(ERROR, + "Requested transfer of %d " + "bytes, max buffer size is " + "%d bytes.\n", size, bufsize); + return -EINVAL; + } + + uncopied_bytes = copy_to_user(ptr, pa->pBuffer, size); + if (uncopied_bytes) + HPI_DEBUG_LOG(WARNING, + "Missed %d of %d " + "bytes to user\n", + uncopied_bytes, size); + } + + mutex_unlock(&adapters[nAdapter].mutex); + } + + /* on return response size must be set */ + if (!hr.wSize) + return -EFAULT; + + /* Copy the response back to user space. */ + uncopied_bytes = copy_to_user(phr, &hr, sizeof(hr)); + if (uncopied_bytes) + return -EFAULT; + return 0; +} + +int __devinit asihpi_adapter_probe( + struct pci_dev *pci_dev, + const struct pci_device_id *pci_id +) +{ + int err, idx; + unsigned int memlen; + struct hpi_message hm; + struct hpi_response hr; + struct hpi_adapter adapter; + struct hpi_pci Pci; + + memset(&adapter, 0, sizeof(adapter)); + + printk(KERN_DEBUG "Probe PCI device (%04x:%04x,%04x:%04x,%04x)\n", + pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor, + pci_dev->subsystem_device, pci_dev->devfn); + + HPI_InitMessage(&hm, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER); + HPI_InitResponse(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER, + HPI_ERROR_PROCESSING_MESSAGE); + + hm.wAdapterIndex = -1; /* an invalid index */ + + /* fill in HPI_PCI information from kernel provided information */ + adapter.pci = pci_dev; + + for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { + HPI_DEBUG_LOG(DEBUG, "Resource %d %s %llx-%llx\n", + idx, pci_dev->resource[idx].name, + (unsigned long long)pci_resource_start(pci_dev, idx), + (unsigned long long)pci_resource_end(pci_dev, idx)); + + memlen = pci_resource_len(pci_dev, idx); + if (memlen) { + adapter.apRemappedMemBase[idx] = + ioremap(pci_resource_start(pci_dev, idx), + memlen); + if (!adapter.apRemappedMemBase[idx]) { + HPI_DEBUG_LOG(ERROR, + "ioremap failed, aborting\n"); + /* unmap previously mapped pci mem space */ + goto err; + } + } else + adapter.apRemappedMemBase[idx] = NULL; + + Pci.apMemBase[idx] = adapter.apRemappedMemBase[idx]; + } + + Pci.wBusNumber = pci_dev->bus->number; + Pci.wVendorId = (u16)pci_dev->vendor; + Pci.wDeviceId = (u16)pci_dev->device; + Pci.wSubSysVendorId = (u16)(pci_dev->subsystem_vendor & 0xffff); + Pci.wSubSysDeviceId = (u16)(pci_dev->subsystem_device & 0xffff); + Pci.wDeviceNumber = pci_dev->devfn; + Pci.wInterrupt = pci_dev->irq; + Pci.pOsData = pci_dev; + + hm.u.s.Resource.wBusType = HPI_BUS_PCI; + hm.u.s.Resource.r.Pci = &Pci; + + /* call CreateAdapterObject on the relevant hpi module */ + HPI_MessageEx(&hm, &hr, HOWNER_KERNEL); + if (hr.wError) + goto err; + + adapter.pBuffer = vmalloc(bufsize); + if (adapter.pBuffer == NULL) { + HPI_DEBUG_LOG(ERROR, + "HPI could not allocate kernel buffer size %d\n", + bufsize); + goto err; + } + + adapter.index = hr.u.s.wAdapterIndex; + adapter.type = hr.u.s.awAdapterList[adapter.index]; + hm.wAdapterIndex = adapter.index; + + err = HPI_AdapterOpen(NULL, adapter.index); + if (err) + goto err; + + adapter.snd_card_asihpi = NULL; + /* WARNING can't init mutex in 'adapter' + * and then copy it to adapters[] ?!?! + */ + adapters[hr.u.s.wAdapterIndex] = adapter; + mutex_init(&adapters[adapter.index].mutex); + pci_set_drvdata(pci_dev, &adapters[adapter.index]); + + /* printk(KERN_INFO + "Probe found adapter ASI%04X HPI index #%d.\n", + adapter.type, + adapter.index); + */ + return 0; + +err: + for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { + if (adapter.apRemappedMemBase[idx]) { + iounmap(adapter.apRemappedMemBase[idx]); + adapter.apRemappedMemBase[idx] = NULL; + } + } + + if (adapter.pBuffer) + vfree(adapter.pBuffer); + + HPI_DEBUG_LOG(ERROR, "adapter_probe failed\n"); + return -ENODEV; +} + +void __devexit asihpi_adapter_remove( + struct pci_dev *pci_dev +) +{ + int idx; + struct hpi_message hm; + struct hpi_response hr; + struct hpi_adapter *pa; + pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev); + + HPI_InitMessage(&hm, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_DELETE_ADAPTER); + hm.wAdapterIndex = pa->index; + HPI_MessageEx(&hm, &hr, HOWNER_KERNEL); + + /* unmap PCI memory space, mapped during device init. */ + for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { + if (pa->apRemappedMemBase[idx]) { + iounmap(pa->apRemappedMemBase[idx]); + pa->apRemappedMemBase[idx] = NULL; + } + } + + if (pa->pBuffer) + vfree(pa->pBuffer); + + pci_set_drvdata(pci_dev, NULL); + /* + printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x)," + " HPI index # %d, removed.\n", + pci_dev->vendor, pci_dev->device, + pci_dev->subsystem_vendor, + pci_dev->subsystem_device, pci_dev->devfn, + pa->index); + */ +} + +void __init asihpi_init( + void +) +{ + struct hpi_message hm; + struct hpi_response hr; + + memset(adapters, 0, sizeof(adapters)); + + /* HPI_DebugLevelSet(debug); now set directly as module param */ + printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n", + HPI_VER_MAJOR(HPI_VER), + HPI_VER_MINOR(HPI_VER), HPI_VER_RELEASE(HPI_VER)); + + HPI_InitMessage(&hm, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_DRIVER_LOAD); + HPI_MessageEx(&hm, &hr, HOWNER_KERNEL); +} + +void asihpi_exit( + void +) +{ + struct hpi_message hm; + struct hpi_response hr; + + HPI_InitMessage(&hm, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_DRIVER_UNLOAD); + HPI_MessageEx(&hm, &hr, HOWNER_KERNEL); +} + +/*********************************************************** +*/ diff --git a/pci/asihpi/hpioctl.h b/pci/asihpi/hpioctl.h new file mode 100644 index 0000000..5363472 --- /dev/null +++ b/pci/asihpi/hpioctl.h @@ -0,0 +1,58 @@ +/******************************************************************************* + + AudioScience HPI driver + Copyright (C) 1997-2003 AudioScience Inc. <support@audioscience.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Linux HPI ioctl, and shared module init functions +*******************************************************************************/ + +int __devinit asihpi_adapter_probe( + struct pci_dev *pci_dev, + const struct pci_device_id *pci_id +); +void __devexit asihpi_adapter_remove( + struct pci_dev *pci_dev +); +void __init asihpi_init( + void +); +void __exit asihpi_exit( + void +); + +int asihpi_hpi_release( + struct file *file +); + +long asihpi_hpi_ioctl( + struct file *file, + unsigned int cmd, + unsigned long arg +); + +/* This is called from hpifunc.c functions, called by ALSA + * (or other kernel process) In this case there is no file descriptor + * available for the message cache code + */ +void HPI_Message( + struct hpi_message *phm, + struct hpi_response *phr +); + +#define HOWNER_KERNEL ((void *)-1) + + /*********************************************************** +*/ -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 2/8] Fix sampleclock source get. Fix volume control dB range. 2008-06-05 4:06 [PATCH - ASIHPI 1/8] Common init files for HPI linux @ 2008-06-05 4:06 ` linux 2008-06-05 4:06 ` [PATCH - ASIHPI 3/8] Replace hpimod.c with hpioctl.c linux 2008-06-05 4:34 ` [PATCH - ASIHPI 1/8] Common init files for HPI Eliot Blennerhassett 1 sibling, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index 538c771..3ffc47b 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -24,9 +24,6 @@ /* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ #define REALLY_VERBOSE_LOGGING 0 -/* Experimental HPI hwdep interface */ -#define EXPERIMENTAL_HWDEP 0 - #if REALLY_VERBOSE_LOGGING #define VPRINTK1 printk #else @@ -50,7 +47,14 @@ #define ASI_STYLE_NAMES 1 #endif +#ifndef KERNEL_ALSA_BUILD +/* building in ALSA source tree */ #include "adriver.h" +#else +/* building in kernel tree */ +#include <sound/driver.h> +#endif + #include <linux/pci.h> #include <linux/version.h> #include <linux/init.h> @@ -68,11 +72,16 @@ #include <sound/hwdep.h> #include "hpi.h" +#include "hpioctl.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("AudioScience Inc. <support@audioscience.com>"); +MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; -static int enable_hpi_hwdep; +static int enable_hpi_hwdep = 1; module_param_array(index, int, NULL, S_IRUGO); MODULE_PARM_DESC(index, "ALSA Index value for AudioScience soundcard."); @@ -85,15 +94,18 @@ MODULE_PARM_DESC(enable, "ALSA Enable AudioScience soundcard."); module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(enable_hpi_hwdep, - "ALSA Enable HPI hwdep for AudioScience soundcard " - "(experimental)"); - -/* used by hpimod.c, stop sparse from complaining */ -int snd_asihpi_bind(struct hpi_adapter *hpi_card); -void snd_asihpi_unbind(struct hpi_adapter *hpi_card); + "ALSA Enable HPI hwdep for AudioScience soundcard "); -/* index base 0 or 1 for control names or indices */ -static const int ixb; +/* identify driver */ +#ifdef KERNEL_ALSA_BUILD +static char * build_info = "Built using headers from kernel source"; +module_param(build_info, charp, S_IRUGO); +MODULE_PARM_DESC(build_info, "Built using headers from kernel source"); +#else +static char * build_info = "Built within ALSA source"; +module_param(build_info, charp, S_IRUGO); +MODULE_PARM_DESC(build_info, "Built within ALSA source"); +#endif /* set to 1 to dump every control from adapter to log */ static const int mixer_dump; @@ -142,6 +154,7 @@ struct snd_card_asihpi { int support_mmap; int support_grouping; + int support_mrx; }; /* Per stream data */ @@ -352,6 +365,89 @@ static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsaFormat, return -EINVAL; } +static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, + struct snd_pcm_hardware *pcmhw) +{ + u16 err; + u32 hControl; + u32 sampleRate; + int idx; + unsigned int rate_min = 200000; + unsigned int rate_max = 0; + unsigned int rates = 0; + + if (asihpi->support_mrx) { + rates |= SNDRV_PCM_RATE_CONTINUOUS; + rates |= SNDRV_PCM_RATE_8000_96000; + rate_min = 8000; + rate_max = 100000; + } else { + /* on cards without SRC, valid rates are determined by sampleclock */ + err = HPI_MixerGetControl(phSubSys, asihpi->hMixer, + HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, + HPI_CONTROL_SAMPLECLOCK, &hControl); + + for (idx=0; idx<100; idx++) { + if (HPI_ControlQuery(phSubSys, hControl, HPI_SAMPLECLOCK_SAMPLERATE, + idx, 0, &sampleRate)) + break; + + rate_min = min(rate_min, sampleRate); + rate_max = max(rate_max, sampleRate); + + switch (sampleRate) { + case 5512: + rates |= SNDRV_PCM_RATE_5512; + break; + case 8000: + rates |= SNDRV_PCM_RATE_8000; + break; + case 11025: + rates |= SNDRV_PCM_RATE_11025; + break; + case 16000: + rates |= SNDRV_PCM_RATE_16000; + break; + case 22050: + rates |= SNDRV_PCM_RATE_22050; + break; + case 32000: + rates |= SNDRV_PCM_RATE_32000; + break; + case 44100: + rates |= SNDRV_PCM_RATE_44100; + break; + case 48000: + rates |= SNDRV_PCM_RATE_48000; + break; + case 64000: + rates |= SNDRV_PCM_RATE_64000; + break; + case 88200: + rates |= SNDRV_PCM_RATE_88200; + break; + case 96000: + rates |= SNDRV_PCM_RATE_96000; + break; + case 176400: + rates |= SNDRV_PCM_RATE_176400; + break; + case 192000: + rates |= SNDRV_PCM_RATE_192000; + break; + default: /* some other rate */ + rates |= SNDRV_PCM_RATE_KNOT; + } + } + } + + /*printk(KERN_INFO "Supported rates %X %d %d\n", rates, rate_min, rate_max); */ + pcmhw->rates = rates; + pcmhw->rate_min = rate_min; + pcmhw->rate_max = rate_max; + +} + static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -784,7 +880,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, u32 hStream, - u64 *formats) + struct snd_pcm_hardware * pcmhw) { struct hpi_format hpi_format; u16 wFormat; @@ -810,7 +906,7 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, err = HPI_OutStreamQueryFormat(phSubSys, hStream, &hpi_format); if (!err && (hpi_to_alsa_formats[wFormat] != -1)) - *formats |= (1ULL << hpi_to_alsa_formats[wFormat]); + pcmhw->formats |= (1ULL << hpi_to_alsa_formats[wFormat]); } } @@ -860,11 +956,10 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) runtime->private_free = snd_card_asihpi_runtime_free; snd_card_asihpi_playback_format(card, dpcm->hStream, - &snd_card_asihpi_playback.formats); - snd_card_asihpi_playback.rates = SNDRV_PCM_RATE_CONTINUOUS | - SNDRV_PCM_RATE_8000_192000; - snd_card_asihpi_playback.rate_min = 5500; - snd_card_asihpi_playback.rate_max = 192000; + &snd_card_asihpi_playback); + + snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback); + snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE; @@ -1006,12 +1101,13 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, u32 hStream, - u64 *formats) + struct snd_pcm_hardware *pcmhw) { struct hpi_format hpi_format; u16 wFormat; u16 err; u32 hControl; + u32 dwSampleRate = 48000; /* on cards without SRC, must query at valid rate, maybe set by external sync */ @@ -1021,20 +1117,21 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, if (!err) err = HPI_SampleClock_GetSampleRate(phSubSys, hControl, - &hpi_format.dwSampleRate); + &dwSampleRate); for (wFormat = HPI_FORMAT_PCM8_UNSIGNED; wFormat <= HPI_FORMAT_PCM24_SIGNED; wFormat++) { - HPI_FormatCreate(&hpi_format, 2, wFormat, 48000, 128000, 0); + HPI_FormatCreate(&hpi_format, 2, wFormat, dwSampleRate, 128000, 0); err = HPI_InStreamQueryFormat(phSubSys, hStream, &hpi_format); if (!err) - *formats |= (1ULL << hpi_to_alsa_formats[wFormat]); + pcmhw->formats |= (1ULL << hpi_to_alsa_formats[wFormat]); } } + static struct snd_pcm_hardware snd_card_asihpi_capture = { .channels_min = 1, .channels_max = 2, @@ -1079,12 +1176,11 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) runtime->private_free = snd_card_asihpi_runtime_free; snd_card_asihpi_capture_format(card, dpcm->hStream, - &snd_card_asihpi_capture.formats); - snd_card_asihpi_capture.rates = SNDRV_PCM_RATE_CONTINUOUS | - SNDRV_PCM_RATE_8000_192000; - snd_card_asihpi_capture.rate_min = 5500; - snd_card_asihpi_capture.rate_max = 192000; + &snd_card_asihpi_capture); + + snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; + if (card->support_mmap) snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID; @@ -1300,50 +1396,29 @@ static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl, return 0; } +/* Convert HPI control name and location into ALSA control name */ static void asihpi_ctl_name(struct snd_kcontrol_new *snd_control, struct hpi_control *asihpi_control, char *name) { -#if 1 -/* entire control ID is a string */ if (asihpi_control->wSrcNodeType && asihpi_control->wDstNodeType) sprintf(snd_control->name, "%s%d to %s%d %s", asihpi_src_names[asihpi_control->wSrcNodeType], - asihpi_control->wSrcNodeIndex + ixb, + asihpi_control->wSrcNodeIndex, asihpi_dst_names[asihpi_control->wDstNodeType], - asihpi_control->wDstNodeIndex + ixb, + asihpi_control->wDstNodeIndex, name); else if (asihpi_control->wDstNodeType) { sprintf(snd_control->name, "%s%d %s", asihpi_dst_names[asihpi_control->wDstNodeType], - asihpi_control->wDstNodeIndex + ixb, + asihpi_control->wDstNodeIndex, name); } else { sprintf(snd_control->name, "%s%d %s", asihpi_src_names[asihpi_control->wSrcNodeType], - asihpi_control->wSrcNodeIndex + ixb, + asihpi_control->wSrcNodeIndex, name); } -#else -/* use string plus index of destination or only node */ - snd_control->index = asihpi_control->wDstNodeIndex + ixb; - if (asihpi_control->wSrcNodeType && asihpi_control->wDstNodeType) - sprintf(snd_control->name, "%s%d to %s %s", - asihpi_src_names[asihpi_control->wSrcNodeType], - asihpi_control->wSrcNodeIndex + ixb, - asihpi_dst_names[asihpi_control->wDstNodeType], - name); - else if (asihpi_control->wDstNodeType) - sprintf(snd_control->name, "%s %s", - asihpi_dst_names[asihpi_control->wDstNodeType], - name); - else { - sprintf(snd_control->name, "%s %s", - asihpi_src_names[asihpi_control->wSrcNodeType], - name); - snd_control->index = asihpi_control->wSrcNodeIndex + ixb; - } -#endif } /*------------------------------------------------------------ @@ -2041,7 +2116,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, sprintf(uinfo->value.enumerated.name, "%s %d", asihpi_src_names[wSrcNodeType - HPI_SOURCENODE_BASE], - wSrcNodeIndex + ixb); + wSrcNodeIndex); return 0; } @@ -2201,15 +2276,16 @@ static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol, (struct snd_card_asihpi *)(kcontrol->private_data); struct clk_cache *clkcache = &asihpi->cc; u32 hControl = kcontrol->private_value; - u16 wSource, wIndex; + u16 wSource, wIndex = 0; int i; ucontrol->value.enumerated.item[0] = 0; - /*Get current clock source, return "N/A" if an error occurs*/ if (HPI_SampleClock_GetSource(phSubSys, hControl, &wSource)) wSource = 0; - if (HPI_SampleClock_GetSourceIndex(phSubSys, hControl, &wIndex)) - wIndex = 0; + + if (wSource == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT) + if (HPI_SampleClock_GetSourceIndex(phSubSys, hControl, &wIndex)) + wIndex = 0; for (i = 0; i < clkcache->count; i++) if ((clkcache->s[i].source == wSource) && @@ -2290,6 +2366,7 @@ static void __devinit snd_asihpi_clksrc_new(struct snd_card_asihpi *asihpi, /*------------------------------------------------------------ Clkrate controls ------------------------------------------------------------*/ +/* Need to change this to enumerated control with list of rates */ static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2335,6 +2412,8 @@ static void __devinit snd_asihpi_clklocal_new( snd_control->info = snd_asihpi_clklocal_info; snd_control->get = snd_asihpi_clklocal_get; snd_control->put = snd_asihpi_clklocal_put; + snd_control->access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; + asihpi_ctl_name(snd_control, asihpi_control, "LocalRate"); } @@ -2425,9 +2504,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) asihpi_control.wDstNodeType -= HPI_DESTNODE_BASE; snd_control.index = 0; snd_control.private_value = hControl; - snd_control.access = - SNDRV_CTL_ELEM_ACCESS_WRITE | - SNDRV_CTL_ELEM_ACCESS_READ; + snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ; switch (asihpi_control.wControlType) { case HPI_CONTROL_VOLUME: snd_asihpi_volume_new(&asihpi_control, @@ -2576,29 +2653,36 @@ static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi) static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file) { - return 0; + if (enable_hpi_hwdep) + return 0; + else + return -ENODEV; + } static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file) { - return 0; + if (enable_hpi_hwdep) + return asihpi_hpi_release(file); + else + return -ENODEV; } -long asihpi_hpi_ioctl(struct file *file, - unsigned int cmd, unsigned long arg); - static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) { - return asihpi_hpi_ioctl(file, cmd, arg); + if (enable_hpi_hwdep) + return asihpi_hpi_ioctl(file, cmd, arg); + else + return -ENODEV; } /* results in /dev/snd/hwC#D0 file for each card with index # also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card' */ -int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device, - struct snd_hwdep **rhwdep) +static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, + int device, struct snd_hwdep **rhwdep) { struct snd_hwdep *hw; int err; @@ -2622,13 +2706,15 @@ int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device, /*------------------------------------------------------------ CARD ------------------------------------------------------------*/ -int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) +int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_id) { int err; u16 wVersion; int pcm_substreams; + struct hpi_adapter *hpi_card; struct snd_card *card; struct snd_card_asihpi *asihpi; @@ -2645,6 +2731,12 @@ int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) return -ENOENT; } + err = asihpi_adapter_probe(pci_dev, pci_id); + if (err < 0) + return err; + + hpi_card = pci_get_drvdata(pci_dev); + /* first try to give the card the same index as its hardware index */ card = snd_card_new(hpi_card->index, id[hpi_card->index], THIS_MODULE, @@ -2672,8 +2764,9 @@ int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) &asihpi->wNumInStreams, &asihpi->wVersion, &asihpi->dwSerialNumber, &asihpi->wType)); + wVersion = asihpi->wVersion; - snd_printk(KERN_INFO "Adapter ID=%4X Index=%d NumOutStreams=%d" + snd_printk(KERN_INFO "Adapter ID=%4X Index=%d NumOutStreams=%d " "NumInStreams=%d S/N=%d\n" "Hw Version %c%d DSP code version %03d\n", asihpi->wType, asihpi->wAdapterIndex, @@ -2695,6 +2788,11 @@ int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) err = HPI_InStreamHostBufferFree(phSubSys, hStream); asihpi->support_mmap = (!err); + + asihpi->support_mrx = (((asihpi->wType & 0xFF00) == 0x8900) || + ((asihpi->wType & 0xF000) == 0x6000)); + + printk(KERN_INFO "Supports mmap:%d grouping:%d\n", asihpi->support_mmap, asihpi->support_grouping); @@ -2717,8 +2815,9 @@ int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) snd_asihpi_proc_init(asihpi); - if (enable_hpi_hwdep) - snd_asihpi_hpi_new(asihpi, 0, NULL); + /* always create, can be enabled or disabled dynamically + by enable_hwdep module param*/ + snd_asihpi_hpi_new(asihpi, 0, NULL); if (asihpi->support_mmap) strcpy(card->driver, "ASIHPI-MMAP"); @@ -2727,7 +2826,7 @@ int __devinit snd_asihpi_bind(struct hpi_adapter *hpi_card) sprintf(card->shortname, "AudioScience ASI%4X", asihpi->wType); sprintf(card->longname, "%s %i", - card->shortname, asihpi->wAdapterIndex + ixb); + card->shortname, asihpi->wAdapterIndex); err = snd_card_register(card); if (!err) { hpi_card->snd_card_asihpi = card; @@ -2740,8 +2839,50 @@ __nodev: } -void snd_asihpi_unbind(struct hpi_adapter *hpi_card) +static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev) { + struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev); + snd_card_free(hpi_card->snd_card_asihpi); hpi_card->snd_card_asihpi = NULL; + asihpi_adapter_remove(pci_dev); +} + +struct pci_device_id asihpi_pci_tbl[] = { + {HPI_PCI_VENDOR_ID_TI, HPI_ADAPTER_DSP6205, + HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0, + (kernel_ulong_t)HPI_6205}, + {HPI_PCI_VENDOR_ID_TI, HPI_ADAPTER_PCI2040, + HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0, + (kernel_ulong_t)HPI_6000}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl); + +static struct pci_driver driver = { + .name = "asihpi", + .id_table = asihpi_pci_tbl, + .probe = snd_asihpi_probe, + .remove = __devexit_p(snd_asihpi_remove), +#ifdef CONFIG_PM +/* .suspend = snd_asihpi_suspend, + .resume = snd_asihpi_resume, */ +#endif +}; + +static int __init snd_asihpi_init(void) +{ + asihpi_init(); + return pci_register_driver(&driver); } + +static void __exit snd_asihpi_exit(void) +{ + + pci_unregister_driver(&driver); + asihpi_exit(); +} + +module_init(snd_asihpi_init) +module_exit(snd_asihpi_exit) + -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 3/8] Replace hpimod.c with hpioctl.c 2008-06-05 4:06 ` [PATCH - ASIHPI 2/8] Fix sampleclock source get. Fix volume control dB range linux @ 2008-06-05 4:06 ` linux 2008-06-05 4:06 ` [PATCH - ASIHPI 4/8] Include pci table again, avoiding warning about extern linux 0 siblings, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/Makefile b/pci/asihpi/Makefile index 6d81cab..942dd84 100644 --- a/pci/asihpi/Makefile +++ b/pci/asihpi/Makefile @@ -5,7 +5,7 @@ endif include $(SND_TOPDIR)/toplevel.config include $(SND_TOPDIR)/Makefile.conf -snd-asihpi-objs := asihpi.o hpimod.o hpimsginit.o\ +snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\ hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\ hpios_linux_kernel.o hpi6000.o hpi6205.o hpimsgx.o -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 4/8] Include pci table again, avoiding warning about extern. 2008-06-05 4:06 ` [PATCH - ASIHPI 3/8] Replace hpimod.c with hpioctl.c linux @ 2008-06-05 4:06 ` linux 2008-06-05 4:06 ` [PATCH - ASIHPI 5/8] Log warning if DSP code version doesn't match driver linux 0 siblings, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/hpimsgx.c b/pci/asihpi/hpimsgx.c index ac56a24..b843e9f 100644 --- a/pci/asihpi/hpimsgx.c +++ b/pci/asihpi/hpimsgx.c @@ -25,7 +25,9 @@ Extended Message Function With Response Cacheing #include "hpimsgx.h" #include "hpidebug.h" -extern struct pci_device_id asihpi_pci_tbl[]; /* hpimod.c mod device tbl */ +static struct pci_device_id asihpi_pci_tbl[] = { +#include "hpipcida.h" +}; static struct hpios_spinlock msgxLock; -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 5/8] Log warning if DSP code version doesn't match driver. 2008-06-05 4:06 ` [PATCH - ASIHPI 4/8] Include pci table again, avoiding warning about extern linux @ 2008-06-05 4:06 ` linux 2008-06-05 4:06 ` [PATCH - ASIHPI 6/8] Version 3.10.00. Add new functions for HD radio tuner, and for firmware debug linux 0 siblings, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/hpidspcd.c b/pci/asihpi/hpidspcd.c index 2665370..8c0f251 100644 --- a/pci/asihpi/hpidspcd.c +++ b/pci/asihpi/hpidspcd.c @@ -56,6 +56,9 @@ struct code_header { #pragma pack(pop) #endif +#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ + HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) + /***********************************************************************/ #include "linux/pci.h" /*-------------------------------------------------------------------*/ @@ -100,6 +103,13 @@ short HpiDspCode_Open( goto error2; } + if (header.version != HPI_VER_DECIMAL) { + HPI_DEBUG_LOG(WARNING, + "Version mismatch DSP image %d != Driver %d\n", + header.version, HPI_VER_DECIMAL); + /* goto error2; still allow driver to load */ + } + HPI_DEBUG_LOG(INFO, "Dsp code %s opened\n", fw_name); psDspCode->psFirmware = psFirmware; psDspCode->dwBlockLength = header.size / sizeof(u32); -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 6/8] Version 3.10.00. Add new functions for HD radio tuner, and for firmware debug. 2008-06-05 4:06 ` [PATCH - ASIHPI 5/8] Log warning if DSP code version doesn't match driver linux @ 2008-06-05 4:06 ` linux 2008-06-05 4:07 ` [PATCH - ASIHPI 7/8] Support variable size cached control information linux 0 siblings, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:06 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/hpi.h b/pci/asihpi/hpi.h index 1656941..a58bf71 100644 --- a/pci/asihpi/hpi.h +++ b/pci/asihpi/hpi.h @@ -41,12 +41,12 @@ i.e 3.05.02 is a development version #define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \ ((maj << 16) + (min << 8) + rel) -#define HPI_VER_MAJOR(v) (v >> 16) -#define HPI_VER_MINOR(v) ((v >> 8) & 0xFF) -#define HPI_VER_RELEASE(v) (v & 0xFF) +#define HPI_VER_MAJOR(v) (int)(v >> 16) +#define HPI_VER_MINOR(v) (int)((v >> 8) & 0xFF) +#define HPI_VER_RELEASE(v) (int)(v & 0xFF) /* Use single digits for versions less that 10 to avoid octal. */ -#define HPI_VER HPI_VERSION_CONSTRUCTOR(3L, 9, 15) +#define HPI_VER HPI_VERSION_CONSTRUCTOR(3L, 10, 0) #ifdef _DOX_ONLY_ /*****************************************************************************/ @@ -191,6 +191,8 @@ extern "C" { #define HPI_ADAPTER_ASI1722 0x1722 /** ASI1731 - Quad TV tuner module */ #define HPI_ADAPTER_ASI1731 0x1731 +/** ASI1741 - Quad HDRadio "pseudo" module */ +#define HPI_ADAPTER_ASI1741 0x1741 /*ASI2214 - USB 2.0 1xanalog in, 4 x analog out, 1 x AES in/out */ /*#define HPI_ADAPTER_ASI2214 0x2214 */ @@ -408,6 +410,8 @@ OBSOLETE - OEM 4 play PCM, MPEG*/ #define HPI_ADAPTER_ASI8801 0x8801 #define HPI_ADAPTER_FAMILY_ASI8900 0x8900 +/** 4 channel AM/FM HD-Radio */ +#define HPI_ADAPTER_ASI8914 0x8914 /** OEM FM+RDS, 2 module tuner card */ #define HPI_ADAPTER_ASI8920 0x8920 /** 2 module tuner card */ @@ -471,7 +475,6 @@ The following table shows what combinations of mode and bitrate are possible: <td><p><b>Mono<br>Stereo @ 16,<br>22.050 and<br>24kHz*</b></p> <td><p><b>Mono<br>Stereo @ 32,<br>44.1 and<br>48kHz</b></p> -<tr><td>8<td>X<td>X<td>_ <tr><td>16<td>X<td>X<td>_ <tr><td>24<td>X<td>X<td>_ <tr><td>32<td>X<td>X<td>X @@ -622,9 +625,10 @@ Audio samples from the device are sent out on the Cobranet network.*/ #define HPI_CONTROL_COBRANET 21 /**< Cobranet control. */ #define HPI_CONTROL_TONEDETECTOR 22 /**< Tone detector control. */ #define HPI_CONTROL_SILENCEDETECTOR 23 /**< Silence detector control. */ +#define HPI_CONTROL_PAD 24 /**< Tuner PAD control. */ /*! Update this if you add a new control type. , AND hpidebug.h */ -#define HPI_CONTROL_LAST_INDEX 23 +#define HPI_CONTROL_LAST_INDEX 24 /* WARNING types 32 or greater impact bit packing in all AX4 DSP code */ /* WARNING types 256 or greater impact bit packing in all AX6 DSP code */ @@ -884,6 +888,9 @@ enum HPI_MIXER_STORE_COMMAND { /* This allows for 255 control types, 256 unique attributes each */ #define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai) +/* Get the sub-index of the attribute for a control type */ +#define HPI_CTL_ATTR_INDEX(i) (i&0xff) + /* Original 0-based non-unique attributes, might become unique later */ #define HPI_CTL_ATTR0(ctl, ai) (ai) @@ -1009,6 +1016,42 @@ enum HPI_MIXER_STORE_COMMAND { #define HPI_TUNER_RDS HPI_CTL_ATTR0(TUNER, 9) /** Audio pre-emphasis. */ #define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10) +/** HD-Radio tuner program control. */ +#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11) +/** HD-Radio tuner digital signal quality. */ +#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12) +/** HD-Radio SDK firmware version. */ +#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13) +/** HD-Radio DSP firmware version. */ +#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14) +/** \} */ + +/** \defgroup pads_attrs Tuner PADs control attributes +\{ +*/ +/** The text string containing the station/channel combination. */ +#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1) +#define HPI_PAD_CHANNEL_NAME_LEN 16 +/** The text string containing the artist. */ +#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2) +#define HPI_PAD_ARTIST_LEN 64 +/** The text string containing the title. */ +#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3) +#define HPI_PAD_TITLE_LEN 64 +/** The text string containing the comment. */ +#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4) +#define HPI_PAD_COMMENT_LEN 256 +/** The integer containing the PTY code. */ +#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5) +/** The integer containing the program identification. */ +#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6) +/** The integer containing whether traffic information is supported. +Contains either 1 or 0. */ +#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7) +/** The integer containing whether traffic announcement is in progress. +Contains either 1 or 0. */ +#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8) + /** \} */ /** \defgroup tuner_bands Tuner bands @@ -1040,13 +1083,21 @@ Used for HPI_Tuner_SetBand(),HPI_Tuner_GetBand() #define HPI_TUNER_LEVEL_AVERAGE 0 #define HPI_TUNER_LEVEL_RAW 1 -/** Tuner video status */ +/** \defgroup tuner_status Tuner status fields + +These bitfield values are returned by a call to HPI_Tuner_GetStatus(). +Multiple fields are returned from a single call. +\{ +*/ #define HPI_TUNER_VIDEO_COLOR_PRESENT 0x0001 /**< Video color is present. */ #define HPI_TUNER_VIDEO_IS_60HZ 0x0020 /**< 60 Hz video detected. */ #define HPI_TUNER_VIDEO_HORZ_SYNC_MISSING 0x0040 /**< Video HSYNC is missing. */ #define HPI_TUNER_VIDEO_STATUS_VALID 0x0100 /**< Video status is valid. */ #define HPI_TUNER_PLL_LOCKED 0x1000 /**< The tuner's PLL is locked. */ #define HPI_TUNER_FM_STEREO 0x2000 /**< Tuner reports back FM stereo. */ +#define HPI_TUNER_DIGITAL 0x0200 /**< Tuner reports digital programming. */ +#define HPI_TUNER_MULITPROGRAM 0x0400 /**< Tuner reports multiple programs. */ +/** \} */ /** \} */ /* VOX control attributes */ @@ -1224,8 +1275,8 @@ enum HPI_FILTER_TYPE { #define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ -/** Base network time out is set to 2 seconds. */ -#define HPI_ETHERNET_TIMEOUT_MS (2000) +/** Base network time out is set to 100 milli-seconds. */ +#define HPI_ETHERNET_TIMEOUT_MS (100) /** \defgroup tonedet_attr Tonedetector attributes \{ @@ -1705,6 +1756,14 @@ u16 HPI_AdapterSelfTest( u16 wAdapterIndex ); +u16 HPI_AdapterDebugRead( + struct hpi_hsubsys *phSubSys, + u16 wAdapterIndex, + u32 dwDspAddress, + char *pBytes, + int *dwCountBytes +); + u16 HPI_AdapterSetProperty( struct hpi_hsubsys *phSubSys, u16 wAdapterIndex, @@ -2363,6 +2422,87 @@ u16 HPI_Tuner_GetDeemphasis( u32 hControl, u32 *pdwDeemphasis ); +u16 HPI_Tuner_SetProgram( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 dwProgram +); +u16 HPI_Tuner_GetProgram( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwProgram +); +u16 HPI_Tuner_GetHdRadioDspVersion( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszDspVersion, + const u32 dwStringSize +); +u16 HPI_Tuner_GetHdRadioSdkVersion( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszSdkVersion, + const u32 dwStringSize +); + +u16 HPI_Tuner_GetHdRadioSignalQuality( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwQuality +); + +/****************************/ +/* PADs control */ +/****************************/ + +u16 HPI_PAD_GetChannelName( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszData, + const u32 dwDataLength +); + +u16 HPI_PAD_GetArtist( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszData, + const u32 dwDataLength +); + +u16 HPI_PAD_GetTitle( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszData, + const u32 dwDataLength +); + +u16 HPI_PAD_GetComment( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszData, + const u32 dwDataLength +); + +u16 HPI_PAD_GetProgramType( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwPTY +); + +u16 HPI_PAD_GetRdsPI( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwPI +); + +u16 HPI_PAD_GetProgramTypeString( + struct hpi_hsubsys *phSubSys, + u32 hControl, + const u32 dwDataType, + const u32 nPTY, + char *pszData, + const u32 dwDataLength +); /****************************/ /* AES/EBU Receiver control */ @@ -2987,7 +3127,8 @@ u16 HPI_FormatCreate( #define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15) #define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16) #define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17) -#define HPI_ADAPTER_FUNCTION_COUNT 17 +#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18) +#define HPI_ADAPTER_FUNCTION_COUNT 18 /* OUTPUT STREAM */ #define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1) #define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2) @@ -3135,7 +3276,7 @@ struct hpi_msg_format { }; /** Buffer+format structure. - Must be kept 7 * 32 bits to match public struct hpi_data HPI_DATAstruct */ + Must be kept 7 * 32 bits to match public struct hpi_datastruct */ struct hpi_msg_data { struct hpi_msg_format Format; u8 *pbData; @@ -3145,7 +3286,7 @@ struct hpi_msg_data { u32 dwDataSize; }; -/** struct hpi_data HPI_DATAstructure used up to 3.04 driver */ +/** struct hpi_datastructure used up to 3.04 driver */ struct hpi_data_legacy32 { struct hpi_format Format; u32 pbData; @@ -3153,7 +3294,7 @@ struct hpi_data_legacy32 { }; #ifdef HPI64BIT -/* Compatibility version of struct hpi_data HPI_DATA*/ +/* Compatibility version of struct hpi_data*/ struct hpi_data_compat32 { struct hpi_msg_format Format; u32 pbData; @@ -3218,6 +3359,10 @@ union hpi_adapterx_msg { struct { u16 index; } module_info; + struct { + u32 dwDspAddress; + u32 dwCountBytes; + } debug_read; }; struct hpi_adapter_res { @@ -3334,7 +3479,7 @@ union hpi_mixerx_msg { union hpi_mixerx_res { struct { - u32 dwBytesReturned; /* number of items returned */ + u32 dwBytesReturned; /* size of items returned */ u32 pData; /* pointer to data array */ u16 wMoreToDo; /* indicates if there is more to do */ } gcabi; @@ -3360,6 +3505,7 @@ struct hpi_control_union_msg { u32 dwGain; u32 dwBand; u32 dwDeemphasis; + u32 dwProgram; struct { u32 dwMode; u32 dwValue; @@ -3394,6 +3540,10 @@ union hpi_control_union_res { u32 dwBLER; } rds; } tuner; + struct { + char szData[8]; + u32 dwRemainingChars; + } chars8; }; /* HPI_CONTROLX_STRUCTURES */ @@ -3419,6 +3569,17 @@ struct hpi_controlx_msg_cobranet_bigdata { #endif }; +/** Used for PADS control reading of string fields. +*/ +struct hpi_controlx_msg_pad_data { + u32 dwField; + u32 dwByteCount; + u8 *pbData; +#ifndef HPI64BIT + u32 dwPadding; +#endif +}; + /** Used for generic data */ @@ -3432,6 +3593,7 @@ struct hpi_controlx_msg { struct hpi_controlx_msg_cobranet_data cobranet_data; struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata; struct hpi_controlx_msg_generic generic; + struct hpi_controlx_msg_pad_data pad_data; /* nothing extra to send for status read */ } u; u16 wControlIndex; @@ -3657,6 +3819,7 @@ struct hpi_response { struct hpi_clock_res t; /* dsp time */ struct hpi_profile_res p; struct hpi_async_res as; + u8 bytes[52]; } u; }; @@ -3696,11 +3859,17 @@ struct hpi_control_defn { Used for efficient transfer of the control state between DSP and host or across a network */ -struct hpi_control_cache_single { +struct hpi_control_cache_info { /** one of HPI_CONTROL_* */ - u16 ControlType; + u8 ControlType; + /** The total size of cached information in 32-bit words. */ + u8 nSizeIn32bitWords; /** The original index of the control on the DSP */ u16 ControlIndex; +}; + +struct hpi_control_cache_single { + struct hpi_control_cache_info i; union { struct { /* volume */ u16 anLog[2]; @@ -3750,6 +3919,20 @@ struct hpi_control_cache_single { } g; } u; }; + +struct hpi_control_cache_pad { + struct hpi_control_cache_info i; + u32 dwFieldValidFlags; + u8 cChannel[8]; + u8 cArtist[40]; + u8 cTitle[40]; + u8 cComment[200]; + u32 dwPTY; + u32 dwPI; + u32 dwTrafficSupported; + u32 dwTrafficAnouncement; +}; + /*/////////////////////////////////////////////////////////////////////////// */ /* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */ struct hpi_fifo_buffer { diff --git a/pci/asihpi/hpidebug.h b/pci/asihpi/hpidebug.h index b8b6f61..d99a685 100644 --- a/pci/asihpi/hpidebug.h +++ b/pci/asihpi/hpidebug.h @@ -170,10 +170,11 @@ void hpi_debug_data( "HPI_ADAPTER_SET_PROPERTY", \ "HPI_ADAPTER_GET_PROPERTY", \ "HPI_ADAPTER_ENUM_PROPERTY", \ - "HPI_ADAPTER_MODULE_INFO" \ + "HPI_ADAPTER_MODULE_INFO", \ + "HPI_ADAPTER_DEBUG_READ" \ } -function_count_check(HPI_ADAPTER, 17); +function_count_check(HPI_ADAPTER, 18); #define HPI_OSTREAM_STRINGS \ { \ @@ -328,9 +329,10 @@ function_count_check(HPI_ASYNCEVENT, 6); "HPI_CONTROL_COBRANET", \ "HPI_CONTROL_TONE_DETECT", \ "HPI_CONTROL_SILENCE_DETECT" \ + "HPI_CONTROL_PAD" \ } -compile_time_assert((HPI_CONTROL_LAST_INDEX + 1) == (24), +compile_time_assert((HPI_CONTROL_LAST_INDEX + 1) == (25), controltype_strings_dont_match_defs); #define HPI_SOURCENODE_STRINGS \ diff --git a/pci/asihpi/hpifunc.c b/pci/asihpi/hpifunc.c index ef61d18..6c33a80 100644 --- a/pci/asihpi/hpifunc.c +++ b/pci/asihpi/hpifunc.c @@ -606,6 +606,35 @@ u16 HPI_AdapterSelfTest( return (hr.wError); } +u16 HPI_AdapterDebugRead( + struct hpi_hsubsys *phSubSys, + u16 wAdapterIndex, + u32 dwDspAddress, + char *pBuffer, + int *dwCountBytes +) +{ + struct hpi_message hm; + struct hpi_response hr; + HPI_InitMessage(&hm, HPI_OBJ_ADAPTER, HPI_ADAPTER_DEBUG_READ); + hm.wAdapterIndex = wAdapterIndex; + hm.u.ax.debug_read.dwDspAddress = dwDspAddress; + + if (*dwCountBytes > sizeof(hr.u.bytes)) + *dwCountBytes = sizeof(hr.u.bytes); + + hm.u.ax.debug_read.dwCountBytes = *dwCountBytes; + + HPI_Message(&hm, &hr); + + if (!hr.wError) { + *dwCountBytes = hr.wSize - 12; + memcpy(pBuffer, &hr.u.bytes, *dwCountBytes); + } else + *dwCountBytes = 0; + return (hr.wError); +} + u16 HPI_AdapterSetProperty( struct hpi_hsubsys *phSubSys, u16 wAdapterIndex, @@ -1692,6 +1721,61 @@ u16 HPI_ControlQuery( return (hr.wError); } +static u16 HPI_Control_GetString( + const struct hpi_hsubsys *phSubSys, + const u32 hControlHandle, + const u16 wAttribute, + char *pszString, + const u32 wStringLength +) +{ + unsigned int subStringIndex = 0, j = 0; + char c = 0; + unsigned int n = 0; + u16 wHE = 0; + + if ((wStringLength < 1) || (wStringLength > 256)) + return HPI_ERROR_INVALID_CONTROL_VALUE; + for (subStringIndex = 0; subStringIndex < wStringLength; + subStringIndex += 8) { + struct hpi_message hm; + struct hpi_response hr; + + HPI_InitMessage(&hm, HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE); + u32TOINDEXES(hControlHandle, &hm.wAdapterIndex, + &hm.u.c.wControlIndex); + hm.u.c.wAttribute = wAttribute; + hm.u.c.dwParam1 = subStringIndex; + hm.u.c.dwParam2 = 0; + HPI_Message(&hm, &hr); + + if (subStringIndex == 0 + && (hr.u.cu.chars8.dwRemainingChars + 8) > + wStringLength) + return HPI_ERROR_INVALID_CONTROL_VALUE; + + if (hr.wError) { + wHE = hr.wError; + break; + } + for (j = 0; j < 8; j++) { + c = hr.u.cu.chars8.szData[j]; + pszString[subStringIndex + j] = c; + n++; + if (n >= wStringLength) { + pszString[wStringLength - 1] = 0; + wHE = HPI_ERROR_INVALID_CONTROL_VALUE; + break; + } + if (c == 0) + break; + } + if (c == 0) + break; + } + return wHE; +} + #if 0 u16 HPI_Tuner_QueryFrequency( @@ -2976,6 +3060,50 @@ u16 HPI_Tuner_GetDeemphasis( pdwDeemphasis); } +u16 HPI_Tuner_SetProgram( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 dwProgram +) +{ + return HPI_ControlParamSet(phSubSys, hControl, HPI_TUNER_PROGRAM, + dwProgram, 0); +} + +u16 HPI_Tuner_GetProgram( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwProgram +) +{ + return HPI_ControlParam1Get(phSubSys, hControl, HPI_TUNER_PROGRAM, + pdwProgram); +} + +u16 HPI_Tuner_GetHdRadioDspVersion( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszDspVersion, + const u32 dwStringSize +) +{ + return HPI_Control_GetString(phSubSys, + hControl, + HPI_TUNER_HDRADIO_DSP_VERSION, pszDspVersion, dwStringSize); +} + +u16 HPI_Tuner_GetHdRadioSdkVersion( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszSdkVersion, + const u32 dwStringSize +) +{ + return HPI_Control_GetString(phSubSys, + hControl, + HPI_TUNER_HDRADIO_SDK_VERSION, pszSdkVersion, dwStringSize); +} + u16 HPI_Tuner_GetStatus( struct hpi_hsubsys *phSubSys, u32 hControl, @@ -3022,6 +3150,16 @@ u16 HPI_Tuner_GetMode( nMode, 0, pnValue, NULL); } +u16 HPI_Tuner_GetHdRadioSignalQuality( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwQuality +) +{ + return HPI_ControlParamGet(phSubSys, hControl, + HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pdwQuality, NULL); +} + u16 HPI_Tuner_GetRDS( struct hpi_hsubsys *phSubSys, u32 hControl, @@ -3042,6 +3180,82 @@ u16 HPI_Tuner_GetRDS( return (hr.wError); } +#ifdef _DOX_ONLY_ +u16 HPI_Tuner_GetHdRadioSignalQuality( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwSignalQuality +) +{ + return HPI_ControlParamGet(phSubSys, hControl, + HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pdwSignalQuality, 0); +} +#endif + +u16 HPI_PAD_GetChannelName( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszString, + const u32 dwDataLength +) +{ + return HPI_Control_GetString(phSubSys, + hControl, HPI_PAD_CHANNEL_NAME, pszString, dwDataLength); +} + +u16 HPI_PAD_GetArtist( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszString, + const u32 dwDataLength +) +{ + return HPI_Control_GetString(phSubSys, + hControl, HPI_PAD_ARTIST, pszString, dwDataLength); +} + +u16 HPI_PAD_GetTitle( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszString, + const u32 dwDataLength +) +{ + return HPI_Control_GetString(phSubSys, + hControl, HPI_PAD_TITLE, pszString, dwDataLength); +} + +u16 HPI_PAD_GetComment( + struct hpi_hsubsys *phSubSys, + u32 hControl, + char *pszString, + const u32 dwDataLength +) +{ + return HPI_Control_GetString(phSubSys, + hControl, HPI_PAD_COMMENT, pszString, dwDataLength); +} + +u16 HPI_PAD_GetProgramType( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwPTY +) +{ + return HPI_ControlParamGet(phSubSys, hControl, HPI_PAD_PROGRAM_TYPE, + 0, 0, pdwPTY, NULL); +} + +u16 HPI_PAD_GetRdsPI( + struct hpi_hsubsys *phSubSys, + u32 hControl, + u32 *pdwPI +) +{ + return HPI_ControlParamGet(phSubSys, hControl, HPI_PAD_PROGRAM_ID, + 0, 0, pdwPI, NULL); +} + u16 HPI_VolumeSetGain( struct hpi_hsubsys *phSubSys, u32 hControl, -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 7/8] Support variable size cached control information. 2008-06-05 4:06 ` [PATCH - ASIHPI 6/8] Version 3.10.00. Add new functions for HD radio tuner, and for firmware debug linux @ 2008-06-05 4:07 ` linux 2008-06-05 4:07 ` [PATCH - ASIHPI 8/8] Checkpatch tweaks linux 0 siblings, 1 reply; 11+ messages in thread From: linux @ 2008-06-05 4:07 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <linux@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/hpi6000.c b/pci/asihpi/hpi6000.c index ec2ae66..6d1834e 100644 --- a/pci/asihpi/hpi6000.c +++ b/pci/asihpi/hpi6000.c @@ -158,6 +158,7 @@ struct hpi_hw_obj { u16 wDspCrashed; /* when '1' DSP has crashed/died/OTL */ struct hpi_control_cache_single aControlCache[HPI_NMIXER_CONTROLS]; + struct hpi_control_cache *pCache; }; static u16 Hpi6000_DspBlockWrite32( @@ -319,8 +320,7 @@ static void ControlMessage( } if (HpiCheckControlCache - (&((struct hpi_hw_obj *)pao->priv)-> - aControlCache[phm->u.c.wControlIndex], + (((struct hpi_hw_obj *)pao->priv)->pCache, phm, phr)) break; } @@ -331,8 +331,8 @@ static void ControlMessage( break; case HPI_CONTROL_SET_STATE: HW_Message(pao, phm, phr); - HpiSyncControlCache(&((struct hpi_hw_obj *)pao->priv)-> - aControlCache[phm->u.c.wControlIndex], phm, phr); + HpiSyncControlCache( + ((struct hpi_hw_obj *)pao->priv)->pCache, phm, phr); break; default: phr->wError = HPI_ERROR_INVALID_FUNC; @@ -431,7 +431,7 @@ void HPI_6000( /* subsytem messages get executed by every HPI. */ /* All other messages are ignored unless the adapter index matches */ /* an adapter in the HPI */ - HPI_DEBUG_LOG(DEBUG, "O %d,F %d\n", phm->wObject, phm->wFunction); + HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); /* if Dsp has crashed then do not communicate with it any more */ if (phm->wObject != HPI_OBJ_SUBSYSTEM) { @@ -573,15 +573,19 @@ static void SubSysDeleteAdapter( ) { struct hpi_adapter_obj *pao = NULL; - void *priv; + struct hpi_hw_obj *phw; pao = HpiFindAdapter(phm->wAdapterIndex); if (!pao) return; - priv = pao->priv; + phw = (struct hpi_hw_obj *)pao->priv; + + if (pao->wHasControlCache) + HpiFreeControlCache(phw->pCache); + HpiDeleteAdapter(pao); - kfree(priv); + kfree(phw); phr->wError = 0; } @@ -594,6 +598,8 @@ static short CreateAdapterObj( { short nBootError = 0; u32 dwDspIndex = 0; + u32 dwControlCacheSize = 0; + u32 dwControlCacheCount = 0; struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; /* init error reporting */ @@ -693,10 +699,18 @@ static short CreateAdapterObj( sizeof(struct hpi_control_cache_single) * HPI_NMIXER_CONTROLS); /* Read the control cache length to figure out if it is turned on */ - if (HpiReadWord - (&phw->ado[0], HPI_HIF_ADDR(dwControlCacheSizeInBytes))) + dwControlCacheSize = HpiReadWord(&phw->ado[0], + HPI_HIF_ADDR(dwControlCacheSizeInBytes)); + if (dwControlCacheSize) { + dwControlCacheCount = HpiReadWord(&phw->ado[0], + HPI_HIF_ADDR(dwControlCacheCount)); pao->wHasControlCache = 1; - else + + phw->pCache = HpiAllocControlCache(dwControlCacheCount, + dwControlCacheSize, (struct hpi_control_cache_info *) + &phw->aControlCache[0] + ); + } else pao->wHasControlCache = 0; HPI_DEBUG_LOG(DEBUG, "Get adapter info ASI%04X index %d\n", diff --git a/pci/asihpi/hpi6000.h b/pci/asihpi/hpi6000.h index ba75b0b..348ad8d 100644 --- a/pci/asihpi/hpi6000.h +++ b/pci/asihpi/hpi6000.h @@ -45,6 +45,7 @@ struct hpi_hif_6000 { u32 dwControlCacheIsDirty; u32 dwControlCacheAddress; u32 dwControlCacheSizeInBytes; + u32 dwControlCacheCount; }; #define HPI_HIF_PACK_ADAPTER_INFO(adapter, versionMajor, versionMinor) \ diff --git a/pci/asihpi/hpi6205.c b/pci/asihpi/hpi6205.c index b74add0..ff010a7 100644 --- a/pci/asihpi/hpi6205.c +++ b/pci/asihpi/hpi6205.c @@ -126,8 +126,10 @@ struct hpi_hw_obj { struct consistent_dma_area hControlCache; struct consistent_dma_area hAsyncEventBuffer; - struct hpi_control_cache_single *pControlCache; +/* struct hpi_control_cache_single *pControlCache; */ struct hpi_async_event *pAsyncEventBuffer; + struct hpi_control_cache *pCache; + }; /*****************************************************************************/ @@ -172,12 +174,6 @@ static void SubSysDeleteAdapter( struct hpi_response *phr ); -static void AdapterGetAsserts( - struct hpi_adapter_obj *pao, - struct hpi_message *phm, - struct hpi_response *phr -); - static u16 CreateAdapterObj( struct hpi_adapter_obj *pao, u32 *pdwOsErrorCode @@ -325,9 +321,7 @@ static void ControlMessage( case HPI_CONTROL_GET_STATE: if (pao->wHasControlCache) { rmb(); /* make sure we see updates DMAed from DSP */ - if (HpiCheckControlCache - (&pHw6205->pControlCache[phm->u.c. - wControlIndex], phm, phr)) + if (HpiCheckControlCache(pHw6205->pCache, phm, phr)) break; } HW_Message(pao, phm, phr); @@ -338,9 +332,7 @@ static void ControlMessage( case HPI_CONTROL_SET_STATE: HW_Message(pao, phm, phr); if (pao->wHasControlCache) - HpiSyncControlCache(&pHw6205-> - pControlCache[phm->u.c. - wControlIndex], phm, phr); + HpiSyncControlCache(pHw6205->pCache, phm, phr); break; default: phr->wError = HPI_ERROR_INVALID_FUNC; @@ -354,14 +346,7 @@ static void AdapterMessage( struct hpi_response *phr ) { - switch (phm->wFunction) { - case HPI_ADAPTER_GET_INFO: - HW_Message(pao, phm, phr); - break; - case HPI_ADAPTER_GET_ASSERT: - AdapterGetAsserts(pao, phm, phr); - break; default: HW_Message(pao, phm, phr); break; @@ -506,6 +491,7 @@ void HPI_6205( AdapterMessage(pao, phm, phr); break; + case HPI_OBJ_CONTROLEX: case HPI_OBJ_CONTROL: ControlMessage(pao, phm, phr); break; @@ -694,20 +680,25 @@ static u16 CreateAdapterObj( * Allocate bus mastering control cache buffer and tell the DSP about it */ if (interface->aControlCache.dwNumberOfControls) { + void *pControlCacheVirtual; + err = HpiOs_LockedMem_Alloc(&pHw6205->hControlCache, - interface->aControlCache. - dwNumberOfControls * - sizeof(struct hpi_control_cache_single), + interface->aControlCache.dwSizeInBytes, pao->Pci.pOsData); if (!err) err = HpiOs_LockedMem_GetVirtAddr(&pHw6205-> - hControlCache, (void *) - &pHw6205->pControlCache); - if (!err) - memset((void *)pHw6205->pControlCache, 0, - interface->aControlCache. - dwNumberOfControls * - sizeof(struct hpi_control_cache_single)); + hControlCache, &pControlCacheVirtual); + if (!err) { + memset(pControlCacheVirtual, 0, + interface->aControlCache.dwSizeInBytes); + + pHw6205->pCache = + HpiAllocControlCache(interface->aControlCache. + dwNumberOfControls, + interface->aControlCache.dwSizeInBytes, + (struct hpi_control_cache_info *) + pControlCacheVirtual); + } if (!err) { err = HpiOs_LockedMem_GetPhysAddr(&pHw6205-> hControlCache, &dwPhysAddr); @@ -718,10 +709,8 @@ static u16 CreateAdapterObj( if (!err) pao->wHasControlCache = 1; else { - if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache)) { + if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache)) HpiOs_LockedMem_Free(&pHw6205->hControlCache); - pHw6205->pControlCache = NULL; - } pao->wHasControlCache = 0; } } @@ -816,7 +805,7 @@ static void DeleteAdapterObj( if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache)) { HpiOs_LockedMem_Free(&pHw6205->hControlCache); - pHw6205->pControlCache = NULL; + HpiFreeControlCache(pHw6205->pCache); } if (HpiOs_LockedMem_Valid(&pHw6205->hLockedMem)) { @@ -846,19 +835,6 @@ static void DeleteAdapterObj( } /*****************************************************************************/ -/* ADAPTER */ - -static void AdapterGetAsserts( - struct hpi_adapter_obj *pao, - struct hpi_message *phm, - struct hpi_response *phr -) -{ - HW_Message(pao, phm, phr); /*get DSP asserts */ - return; -} - -/*****************************************************************************/ /* OutStream Host buffer functions */ /** Allocate or attach buffer for busmastering diff --git a/pci/asihpi/hpi6205.h b/pci/asihpi/hpi6205.h index c5309cb..2c92d59 100644 --- a/pci/asihpi/hpi6205.h +++ b/pci/asihpi/hpi6205.h @@ -67,7 +67,7 @@ This is used for dynamic control cache allocation struct controlcache_6205 { u32 dwNumberOfControls; u32 dwPhysicalPCI32address; - u32 dwSpare; + u32 dwSizeInBytes; }; /********************************************************************* diff --git a/pci/asihpi/hpicmn.c b/pci/asihpi/hpicmn.c index 29fe40f..af83a2e 100644 --- a/pci/asihpi/hpicmn.c +++ b/pci/asihpi/hpicmn.c @@ -21,6 +21,7 @@ (C) Copyright AudioScience Inc. 1998-2003 *******************************************************************************/ #define SOURCEFILE_NAME "hpicmn.c" + #include "hpi.h" #include "hpidebug.h" #include "hpicmn.h" @@ -106,12 +107,16 @@ struct hpi_adapter_obj *HpiFindAdapter( pao = &adapters.adapter[wAdapterIndex]; if (pao->wAdapterType != 0) { - HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n", - wAdapterIndex); + /* + HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n", + wAdapterIndex); + */ return (pao); } else { - HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n", - wAdapterIndex); + /* + HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n", + wAdapterIndex); + */ return (NULL); } } @@ -171,25 +176,141 @@ static void SubSysGetAdapters( phr->wError = 0; /* the function completed OK; */ } -/** -* CheckControlCache checks if a given struct hpi_control_cache_single control -* value is in the cache and fills the struct hpi_response accordingly. -* It returns nonzero if a cache hit occurred, zero otherwise. +static unsigned int ControlCacheAllocCheck( + struct hpi_control_cache *pC +) +{ + unsigned int i; + int nCached = 0; + if (!pC) + return 0; + if ((!pC->dwInit) && + (pC->pCache != NULL) && + (pC->dwControlCount) && (pC->dwCacheSizeInBytes) + ) { + u32 *pMasterCache; + pC->dwInit = 1; + + pMasterCache = (u32 *)pC->pCache; + for (i = 0; i < pC->dwControlCount; i++) { + struct hpi_control_cache_info *info = + (struct hpi_control_cache_info *)pMasterCache; + + if (info->ControlType) { + pC->pInfo[i] = info; + nCached++; + } else + pC->pInfo[i] = NULL; + + if (info->nSizeIn32bitWords) + pMasterCache += info->nSizeIn32bitWords; + else + pMasterCache += + sizeof(struct + hpi_control_cache_single) / + sizeof(u32); + + } + /* + We didn't find anything to cache, so try again later ! + */ + if (!nCached) + pC->dwInit = 0; + } + return pC->dwInit; +} + +/** Find a control. +*/ +static short FindControl( + struct hpi_message *phm, + struct hpi_control_cache *pCache, + struct hpi_control_cache_info **pI, + u16 *pwControlIndex +) +{ + if (phm->wObject == HPI_OBJ_CONTROL) { + *pwControlIndex = phm->u.c.wControlIndex; + } else { /* controlex */ + *pwControlIndex = phm->u.cx.wControlIndex; + HPI_DEBUG_LOG(VERBOSE, + "HpiCheckControlCache() ControlEx %d\n", + *pwControlIndex); + } + + if (!ControlCacheAllocCheck(pCache)) { + HPI_DEBUG_LOG(VERBOSE, + "ControlCacheAllocCheck() failed. adap%d ci%d\n", + phm->wAdapterIndex, *pwControlIndex); + return 0; + } + + *pI = pCache->pInfo[*pwControlIndex]; + if (!*pI) { + HPI_DEBUG_LOG(VERBOSE, + "Uncached Adap %d, Control %d\n", + phm->wAdapterIndex, *pwControlIndex); + return 0; + } else { + HPI_DEBUG_LOG(VERBOSE, + "HpiCheckControlCache() Type %d\n", + (*pI)->ControlType); + } + return 1; +} + +/** Used by the kernel driver to figure out if a buffer needs mapping. + */ +short HpiCheckBufferMapping( + struct hpi_control_cache *pCache, + struct hpi_message *phm, + void **p, + unsigned int *pN +) +{ + *pN = 0; + *p = NULL; + if ((phm->wFunction == HPI_CONTROL_GET_STATE) && + (phm->wObject == HPI_OBJ_CONTROLEX) + ) { + u16 wControlIndex; + struct hpi_control_cache_info *pI; + + if (!FindControl(phm, pCache, &pI, &wControlIndex)) + return 0; + } + return 0; +} + +/** CheckControlCache checks the cache and fills the struct hpi_response +* accordingly. It returns one if a cache hit occurred, zero otherwise. */ short HpiCheckControlCache( - struct hpi_control_cache_single *pC, + struct hpi_control_cache *pCache, struct hpi_message *phm, struct hpi_response *phr ) { short found = 1; - /* if the control type in the cache is non-zero then */ - /* we have cached control information to process */ + u16 wControlIndex; + struct hpi_control_cache_info *pI; + struct hpi_control_cache_single *pC; + + if (!FindControl(phm, pCache, &pI, &wControlIndex)) + return 0; + phr->wSize = sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res); phr->wError = 0; - switch (pC->ControlType) { + + /* pC is the default cached control strucure. May be cast to + something else in the following switch statement. + */ + pC = (struct hpi_control_cache_single *)pI; + + switch (pI->ControlType) { + case HPI_CONTROL_METER: if (phm->u.c.wAttribute == HPI_METER_PEAK) { phr->u.c.anLogValue[0] = pC->u.p.anLogPeak[0]; @@ -198,45 +319,50 @@ short HpiCheckControlCache( phr->u.c.anLogValue[0] = pC->u.p.anLogRMS[0]; phr->u.c.anLogValue[1] = pC->u.p.anLogRMS[1]; } else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_VOLUME: if (phm->u.c.wAttribute == HPI_VOLUME_GAIN) { phr->u.c.anLogValue[0] = pC->u.v.anLog[0]; phr->u.c.anLogValue[1] = pC->u.v.anLog[1]; } else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_MULTIPLEXER: if (phm->u.c.wAttribute == HPI_MULTIPLEXER_SOURCE) { phr->u.c.dwParam1 = pC->u.x.wSourceNodeType; phr->u.c.dwParam2 = pC->u.x.wSourceNodeIndex; } else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_CHANNEL_MODE: if (phm->u.c.wAttribute == HPI_CHANNEL_MODE_MODE) phr->u.c.dwParam1 = pC->u.m.wMode; else - found = 0; /* signal that message was not cached */ - + found = 0; + break; case HPI_CONTROL_LEVEL: if (phm->u.c.wAttribute == HPI_LEVEL_GAIN) { phr->u.c.anLogValue[0] = pC->u.l.anLog[0]; phr->u.c.anLogValue[1] = pC->u.l.anLog[1]; } else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_TUNER: - if (phm->u.c.wAttribute == HPI_TUNER_FREQ) - phr->u.c.dwParam1 = pC->u.t.dwFreqInkHz; - else if (phm->u.c.wAttribute == HPI_TUNER_BAND) - phr->u.c.dwParam1 = pC->u.t.wBand; - else if ((phm->u.c.wAttribute == HPI_TUNER_LEVEL) && - (phm->u.c.dwParam1 == HPI_TUNER_LEVEL_AVERAGE)) - phr->u.c.dwParam1 = pC->u.t.wLevel; - else - found = 0; /* signal that message was not cached */ + { + struct hpi_control_cache_single *pCT = + (struct hpi_control_cache_single *)pI; + if (phm->u.c.wAttribute == HPI_TUNER_FREQ) + phr->u.c.dwParam1 = pCT->u.t.dwFreqInkHz; + else if (phm->u.c.wAttribute == HPI_TUNER_BAND) + phr->u.c.dwParam1 = pCT->u.t.wBand; + else if ((phm->u.c.wAttribute == HPI_TUNER_LEVEL) && + (phm->u.c.dwParam1 == + HPI_TUNER_LEVEL_AVERAGE)) + phr->u.c.dwParam1 = pCT->u.t.wLevel; + else + found = 0; + } break; case HPI_CONTROL_AESEBU_RECEIVER: if (phm->u.c.wAttribute == HPI_AESEBURX_ERRORSTATUS) @@ -244,26 +370,26 @@ short HpiCheckControlCache( else if (phm->u.c.wAttribute == HPI_AESEBURX_FORMAT) phr->u.c.dwParam1 = pC->u.aes3rx.dwSource; else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_AESEBU_TRANSMITTER: if (phm->u.c.wAttribute == HPI_AESEBUTX_FORMAT) phr->u.c.dwParam1 = pC->u.aes3tx.dwFormat; else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_TONEDETECTOR: if (phm->u.c.wAttribute == HPI_TONEDETECTOR_STATE) phr->u.c.dwParam1 = pC->u.tone.wState; else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_SILENCEDETECTOR: if (phm->u.c.wAttribute == HPI_SILENCEDETECTOR_STATE) { phr->u.c.dwParam1 = pC->u.silence.dwState; phr->u.c.dwParam2 = pC->u.silence.dwCount; } else - found = 0; /* signal that message was not cached */ + found = 0; break; case HPI_CONTROL_SAMPLECLOCK: if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SOURCE) @@ -278,17 +404,105 @@ short HpiCheckControlCache( } else if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SAMPLERATE) phr->u.c.dwParam1 = pC->u.clk.dwSampleRate; else - found = 0; /* signal that message was not cached */ + found = 0; + break; +#ifndef HPI_OS_WIN16 /* SGT - below does not compile in Borland C */ + case HPI_CONTROL_PAD: + { + struct hpi_control_cache_pad *pPad = + (struct hpi_control_cache_pad *)pC; + + if (!(pPad->dwFieldValidFlags & + (1 << HPI_CTL_ATTR_INDEX(phm->u.c. + wAttribute)))) { + /* attribute not supported */ + phr->wError = + HPI_ERROR_INVALID_CONTROL_ATTRIBUTE; + break; + } + + if (phm->u.c.wAttribute == HPI_PAD_PROGRAM_ID) + phr->u.c.dwParam1 = pPad->dwPI; + else if (phm->u.c.wAttribute == HPI_PAD_PROGRAM_TYPE) + phr->u.c.dwParam1 = pPad->dwPTY; + else { + struct attribs { + u8 *pData; + unsigned int nSize; + }; + struct attribs aDesc[] = { + {NULL, 0}, + /* HPI_PAD_CHANNEL_NAME */ + {pPad->cChannel, sizeof(pPad-> + cChannel)} + , + /* HPI_PAD_ARTIST */ + {pPad->cArtist, sizeof(pPad->cArtist)} + , + /* HPI_PAD_TITLE */ + {pPad->cTitle, sizeof(pPad->cTitle)} + , + /* HPI_PAD_COMMENT */ + {pPad->cComment, sizeof(pPad-> + cComment)} + , + }; + + const u32 dwAttribute = phm->u.c.wAttribute; + const u32 dwIndex = + HPI_CTL_ATTR_INDEX(dwAttribute); + const u32 dwOffset = phm->u.c.dwParam1; + int nStringLength = 0; + int nRemainingChars = 0; + + HPI_DEBUG_LOG(VERBOSE, "PADS control\n"); + + /* check the field type */ + HPI_DEBUG_LOG(VERBOSE, + "PADS HPI_PADS_ %d\n", dwAttribute); + + switch (dwAttribute) { + case HPI_PAD_CHANNEL_NAME: + case HPI_PAD_ARTIST: + case HPI_PAD_TITLE: + case HPI_PAD_COMMENT: + break; + default: + phr->wError = HPI_ERROR_INVALID_FUNC; + } + if (phr->wError) + break; + + nStringLength = strlen(aDesc[dwIndex].pData); + if (dwOffset > (unsigned)nStringLength) { + phr->wError = + HPI_ERROR_INVALID_CONTROL_VALUE; + break; + } + HPI_DEBUG_LOG(VERBOSE, + "PADS memcpy (%d), offset %d \n", + 8, dwOffset); + memcpy(&phr->u.cu.chars8.szData[0], + &aDesc[dwIndex].pData[dwOffset], 8); + nRemainingChars = + nStringLength - dwOffset - 8; + if (nRemainingChars < 0) + nRemainingChars = 0; + phr->u.cu.chars8.dwRemainingChars = + nRemainingChars; + } + } break; +#endif default: - found = 0; /* signal that message was not cached */ + found = 0; break; } - if (found == 0) - HPI_DEBUG_LOG(VERBOSE, "Adap %d, Control %d, " - "Control type %d, Cached %d\n", - phm->wAdapterIndex, pC->ControlIndex, - pC->ControlType, found); + if (pI->ControlType && !found) + HPI_DEBUG_LOG(VERBOSE, + "Uncached Adap %d, Control %d, Control type %d\n", + phm->wAdapterIndex, pI->ControlIndex, + pI->ControlType); return found; } @@ -300,15 +514,24 @@ Volume and Level return the limited values in the response, so use these Multiplexer does so use sent values */ void HpiSyncControlCache( - struct hpi_control_cache_single *pC, + struct hpi_control_cache *pCache, struct hpi_message *phm, struct hpi_response *phr ) { - if (phr->wError) + u16 wControlIndex; + struct hpi_control_cache_single *pC; + struct hpi_control_cache_info *pI; + + if (!FindControl(phm, pCache, &pI, &wControlIndex)) return; - switch (pC->ControlType) { + /* pC is the default cached control strucure. + May be cast to something else in the following switch statement. + */ + pC = (struct hpi_control_cache_single *)pI; + + switch (pI->ControlType) { case HPI_CONTROL_VOLUME: if (phm->u.c.wAttribute == HPI_VOLUME_GAIN) { pC->u.v.anLog[0] = phr->u.c.anLogValue[0]; @@ -323,8 +546,8 @@ void HpiSyncControlCache( } break; case HPI_CONTROL_CHANNEL_MODE: - /* mux does not return its setting on Set command. */ - if (phm->u.c.wAttribute == HPI_MULTIPLEXER_SOURCE) + /* mode does not return its setting on Set command. */ + if (phm->u.c.wAttribute == HPI_CHANNEL_MODE_MODE) pC->u.m.wMode = (u16)phm->u.c.dwParam1; break; case HPI_CONTROL_LEVEL: @@ -340,6 +563,7 @@ void HpiSyncControlCache( case HPI_CONTROL_AESEBU_RECEIVER: if (phm->u.c.wAttribute == HPI_AESEBURX_FORMAT) pC->u.aes3rx.dwSource = phm->u.c.dwParam1; + break; case HPI_CONTROL_SAMPLECLOCK: if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SOURCE) pC->u.clk.wSource = (u16)phm->u.c.dwParam1; @@ -358,6 +582,35 @@ void HpiSyncControlCache( break; } } +struct hpi_control_cache *HpiAllocControlCache( + const u32 dwNumberOfControls, + const u32 dwSizeInBytes, + struct hpi_control_cache_info *pDSPControlBuffer +) +{ + struct hpi_control_cache *pCache = + kmalloc(sizeof(*pCache), GFP_KERNEL); + pCache->dwCacheSizeInBytes = dwSizeInBytes; + pCache->dwControlCount = dwNumberOfControls; + pCache->pCache = (struct hpi_control_cache_single *)pDSPControlBuffer; + pCache->dwInit = 0; + pCache->pInfo = + kmalloc(sizeof(*pCache->pInfo) * pCache->dwControlCount, + GFP_KERNEL); + return pCache; +} + +void HpiFreeControlCache( + struct hpi_control_cache *pCache +) +{ + if ((pCache->dwInit) && (pCache->pInfo)) { + kfree(pCache->pInfo); + pCache->pInfo = NULL; + pCache->dwInit = 0; + kfree(pCache); + } +} static void SubSysMessage( struct hpi_message *phm, diff --git a/pci/asihpi/hpicmn.h b/pci/asihpi/hpicmn.h index 4b7692a..b0763e2 100644 --- a/pci/asihpi/hpicmn.h +++ b/pci/asihpi/hpicmn.h @@ -32,6 +32,18 @@ struct hpi_adapter_obj { void *priv; }; +struct hpi_control_cache { + u32 dwInit; /**< indicates whether the + structures are initialized */ + u32 dwControlCount; + u32 dwCacheSizeInBytes; + struct hpi_control_cache_info + **pInfo; /**< pointer to allocated memory of + lookup pointers. */ + struct hpi_control_cache_single + *pCache; /**< pointer to DSP's control cache. */ +}; + struct hpi_adapter_obj *HpiFindAdapter( u16 wAdapterIndex ); @@ -44,12 +56,22 @@ void HpiDeleteAdapter( ); short HpiCheckControlCache( - struct hpi_control_cache_single *pC, + struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr ); +struct hpi_control_cache *HpiAllocControlCache( + const u32 dwNumberOfControls, + const u32 dwSizeInBytes, + struct hpi_control_cache_info + *pDSPControlBuffer +); +void HpiFreeControlCache( + struct hpi_control_cache *pCache +); + void HpiSyncControlCache( - struct hpi_control_cache_single *pC, + struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr ); @@ -57,3 +79,9 @@ u16 HpiValidateResponse( struct hpi_message *phm, struct hpi_response *phr ); +short HpiCheckBufferMapping( + struct hpi_control_cache *pCache, + struct hpi_message *phm, + void **p, + unsigned int *pN +); -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH - ASIHPI 8/8] Checkpatch tweaks 2008-06-05 4:07 ` [PATCH - ASIHPI 7/8] Support variable size cached control information linux @ 2008-06-05 4:07 ` linux 0 siblings, 0 replies; 11+ messages in thread From: linux @ 2008-06-05 4:07 UTC (permalink / raw) To: tiwai; +Cc: Eliot Blennerhassett, alsa-devel From: Eliot Blennerhassett <eblennerhassett@audioscience.com> Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com> diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index 3ffc47b..8cbefab 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -98,11 +98,11 @@ MODULE_PARM_DESC(enable_hpi_hwdep, /* identify driver */ #ifdef KERNEL_ALSA_BUILD -static char * build_info = "Built using headers from kernel source"; +static char *build_info = "Built using headers from kernel source"; module_param(build_info, charp, S_IRUGO); MODULE_PARM_DESC(build_info, "Built using headers from kernel source"); #else -static char * build_info = "Built within ALSA source"; +static char *build_info = "Built within ALSA source"; module_param(build_info, charp, S_IRUGO); MODULE_PARM_DESC(build_info, "Built within ALSA source"); #endif @@ -382,14 +382,16 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, rate_min = 8000; rate_max = 100000; } else { - /* on cards without SRC, valid rates are determined by sampleclock */ + /* on cards without SRC, + valid rates are determined by sampleclock */ err = HPI_MixerGetControl(phSubSys, asihpi->hMixer, HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0, HPI_CONTROL_SAMPLECLOCK, &hControl); - for (idx=0; idx<100; idx++) { - if (HPI_ControlQuery(phSubSys, hControl, HPI_SAMPLECLOCK_SAMPLERATE, - idx, 0, &sampleRate)) + for (idx = 0; idx < 100; idx++) { + if (HPI_ControlQuery(phSubSys, hControl, + HPI_SAMPLECLOCK_SAMPLERATE, idx, 0, + &sampleRate)) break; rate_min = min(rate_min, sampleRate); @@ -441,7 +443,8 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, } } - /*printk(KERN_INFO "Supported rates %X %d %d\n", rates, rate_min, rate_max); */ + /*printk(KERN_INFO "Supported rates %X %d %d\n", + rates, rate_min, rate_max); */ pcmhw->rates = rates; pcmhw->rate_min = rate_min; pcmhw->rate_max = rate_max; @@ -880,7 +883,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, u32 hStream, - struct snd_pcm_hardware * pcmhw) + struct snd_pcm_hardware *pcmhw) { struct hpi_format hpi_format; u16 wFormat; @@ -906,7 +909,8 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, err = HPI_OutStreamQueryFormat(phSubSys, hStream, &hpi_format); if (!err && (hpi_to_alsa_formats[wFormat] != -1)) - pcmhw->formats |= (1ULL << hpi_to_alsa_formats[wFormat]); + pcmhw->formats |= + (1ULL << hpi_to_alsa_formats[wFormat]); } } @@ -1122,12 +1126,14 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, for (wFormat = HPI_FORMAT_PCM8_UNSIGNED; wFormat <= HPI_FORMAT_PCM24_SIGNED; wFormat++) { - HPI_FormatCreate(&hpi_format, 2, wFormat, dwSampleRate, 128000, 0); - err = - HPI_InStreamQueryFormat(phSubSys, hStream, + HPI_FormatCreate( + &hpi_format, 2, wFormat, dwSampleRate, 128000, 0); + + err = HPI_InStreamQueryFormat(phSubSys, hStream, &hpi_format); if (!err) - pcmhw->formats |= (1ULL << hpi_to_alsa_formats[wFormat]); + pcmhw->formats |= + (1ULL << hpi_to_alsa_formats[wFormat]); } } @@ -2790,7 +2796,7 @@ int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->support_mmap = (!err); asihpi->support_mrx = (((asihpi->wType & 0xFF00) == 0x8900) || - ((asihpi->wType & 0xF000) == 0x6000)); + ((asihpi->wType & 0xF000) == 0x6000)); printk(KERN_INFO "Supports mmap:%d grouping:%d\n", -- 1.5.4.3 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH - ASIHPI 1/8] Common init files for HPI 2008-06-05 4:06 [PATCH - ASIHPI 1/8] Common init files for HPI linux 2008-06-05 4:06 ` [PATCH - ASIHPI 2/8] Fix sampleclock source get. Fix volume control dB range linux @ 2008-06-05 4:34 ` Eliot Blennerhassett 2008-06-06 10:34 ` Takashi Iwai 1 sibling, 1 reply; 11+ messages in thread From: Eliot Blennerhassett @ 2008-06-05 4:34 UTC (permalink / raw) To: tiwai; +Cc: alsa-devel Hi Takashi, this patchset updates ALSA to our current 3.10.00 release. Matching firmware is here, please use it to update alsa-firmware http://audioscience.com/internet/download/firmware/dspbins31000.zip One thing I haven't figured out how to get git to include a patch for deletion of a file? Anyway, current repo hpimod.c is replaced with hpioctl.c (you could consider this a rename then update) I have restructured code a bit so that asihpi.c is the "master" module file, that calls utility functions in hpioctl.c for setting up HPI, and handling hpi ioctl via hwdep. regards Eliot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH - ASIHPI 1/8] Common init files for HPI 2008-06-05 4:34 ` [PATCH - ASIHPI 1/8] Common init files for HPI Eliot Blennerhassett @ 2008-06-06 10:34 ` Takashi Iwai 2008-06-11 23:22 ` Eliot Blennerhassett 0 siblings, 1 reply; 11+ messages in thread From: Takashi Iwai @ 2008-06-06 10:34 UTC (permalink / raw) To: Eliot Blennerhassett; +Cc: alsa-devel At Thu, 05 Jun 2008 16:34:25 +1200, Eliot Blennerhassett wrote: > > Hi Takashi, > > this patchset updates ALSA to our current 3.10.00 release. > Matching firmware is here, please use it to update alsa-firmware > http://audioscience.com/internet/download/firmware/dspbins31000.zip Thanks, updated both alsa-driver and alsa-firmware repos. > One thing I haven't figured out how to get git to include a patch for deletion > of a file? Anyway, current repo hpimod.c is replaced with hpioctl.c (you > could consider this a rename then update) Just use git-mv, and git-format-patch would give you a right patch. (And since I didn't notice this beforehand, I had to re-commit the tree to handle it...) > I have restructured code a bit so that asihpi.c is the "master" module file, > that calls utility functions in hpioctl.c for setting up HPI, and handling > hpi ioctl via hwdep. This looks good! Let's continue to reshape a bit for merging to the upstream. thanks, Takashi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH - ASIHPI 1/8] Common init files for HPI 2008-06-06 10:34 ` Takashi Iwai @ 2008-06-11 23:22 ` Eliot Blennerhassett 0 siblings, 0 replies; 11+ messages in thread From: Eliot Blennerhassett @ 2008-06-11 23:22 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel Takashi Iwai wrote: > At Thu, 05 Jun 2008 16:34:25 +1200, > Eliot Blennerhassett wrote: >> I have restructured code a bit so that asihpi.c is the "master" module file, >> that calls utility functions in hpioctl.c for setting up HPI, and handling >> hpi ioctl via hwdep. > > This looks good! Let's continue to reshape a bit for merging to the > upstream. Thanks Takashi. What sort of reshape do you have in mind? *me* Holds breath... ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-06-11 23:23 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-05 4:06 [PATCH - ASIHPI 1/8] Common init files for HPI linux 2008-06-05 4:06 ` [PATCH - ASIHPI 2/8] Fix sampleclock source get. Fix volume control dB range linux 2008-06-05 4:06 ` [PATCH - ASIHPI 3/8] Replace hpimod.c with hpioctl.c linux 2008-06-05 4:06 ` [PATCH - ASIHPI 4/8] Include pci table again, avoiding warning about extern linux 2008-06-05 4:06 ` [PATCH - ASIHPI 5/8] Log warning if DSP code version doesn't match driver linux 2008-06-05 4:06 ` [PATCH - ASIHPI 6/8] Version 3.10.00. Add new functions for HD radio tuner, and for firmware debug linux 2008-06-05 4:07 ` [PATCH - ASIHPI 7/8] Support variable size cached control information linux 2008-06-05 4:07 ` [PATCH - ASIHPI 8/8] Checkpatch tweaks linux 2008-06-05 4:34 ` [PATCH - ASIHPI 1/8] Common init files for HPI Eliot Blennerhassett 2008-06-06 10:34 ` Takashi Iwai 2008-06-11 23:22 ` Eliot Blennerhassett
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.