Update of /cvsroot/alsa/alsa-driver/pci/pdplus
In directory sc8-pr-cvs1:/tmp/cvs-serv8373
Modified Files:
pdplus.c
Log Message:
- fixed to use the new PCM API and SPDIF controls.
UNTESTED AT ALL!! please report if someone has this card.
Index: pdplus.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/pci/pdplus/pdplus.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- pdplus.c 21 Oct 2002 18:51:04 -0000 1.9
+++ pdplus.c 7 Jan 2003 10:42:03 -0000 1.10
@@ -75,7 +75,6 @@
* BUGS (These are TODOs, too!):
*
* TODO (prio in parens):
- * (8) use snd_magic_cast
* (6) Make volume linear.
* (6) Introduce de-emphasis mixer control (multiple choice)
* This is hard: pre_effect is neither implemented in mid-level, nor in
@@ -147,8 +146,20 @@
* PLX 9050 PCI bridge.
*
*/
+/*
+ * Changes:
+ *
+ * Ver.0.0.5 Takashi Iwai <[EMAIL PROTECTED]>
+ * - Rewritten the old PCM ioctl callbacks with h/w constraints.
+ * - Rewritten the SPDIF status setting with the standard controls.
+ * - Fixed __init and __exit prefixes.
+ * - Replaced __inline__ with inline.
+ * - Fixed the struct initialization in C99 style.
+ * - Fixed compile warnings.
+ */
-#define PDPLUS_VERSION "0.0.4"
+
+#define PDPLUS_VERSION "0.0.5"
#include <sound/driver.h>
#include <asm/io.h>
@@ -158,6 +169,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#define SNDRV_GET_ID
#include <sound/initval.h>
#include <sound/info.h>
@@ -384,7 +396,7 @@
* General macros for IO */
#if REG_DEBUG
-static __inline__ u32 readl_trace (u_long addr)
+inline static u32 readl_trace (u_long addr)
{
u32 result;
result = readl (addr);
@@ -392,13 +404,13 @@
return result;
}
-static __inline__ void writel_trace (u32 val, u_long addr)
+inline static void writel_trace (u32 val, u_long addr)
{
DL(9, "writel(0x%x,0x%lx)", val,addr);
writel (val, addr);
}
-static __inline__ u32 inl_trace (u_long addr)
+inline static u32 inl_trace (u_long addr)
{
u32 result;
@@ -1307,13 +1319,7 @@
/*
* The private control structure of the driver */
-#ifndef pdplus_t_magic
-#define pdplus_t_magic 0xa15a2d01
-#endif
typedef struct pdplus_stru {
-#if DEBUG
- u32 magic;
-#endif
/* Parents */
pci_dev_t *pci;
snd_card_t *card;
@@ -1370,9 +1376,6 @@
* Mixer */
snd_kmixer_t *mixer;
- /* Entry in /proc directory */
- snd_info_entry_t *proc_entry;
-
/* Values of registers */
u32 PLX_CTRL_val;
u32 PLX_INTCSR_val;
@@ -1421,12 +1424,10 @@
static void pdplus_sweep (snd_card_t *) __exit;
-static int pdplus_a_ioctl (snd_pcm_substream_t *, u_int, void *);
static int pdplus_a_play_prepare (snd_pcm_substream_t *);
static int pdplus_a_play_trigger (snd_pcm_substream_t *, int);
static snd_pcm_uframes_t pdplus_a_play_pointer (snd_pcm_substream_t *);
-static int pdplus_d_play_ioctl (snd_pcm_substream_t *, u_int, void *);
static int pdplus_d_play_prepare (snd_pcm_substream_t *);
static int pdplus_d_play_trigger (snd_pcm_substream_t *, int);
static snd_pcm_uframes_t pdplus_d_play_pointer (snd_pcm_substream_t *);
@@ -1435,7 +1436,6 @@
static int pdplus_a_capt_trigger (snd_pcm_substream_t *, int);
static snd_pcm_uframes_t pdplus_a_capt_pointer (snd_pcm_substream_t *);
-static int pdplus_d_capt_ioctl (snd_pcm_substream_t *, u_int, void *);
static int pdplus_d_capt_prepare (snd_pcm_substream_t *);
static int pdplus_d_capt_trigger (snd_pcm_substream_t *, int);
static snd_pcm_uframes_t pdplus_d_capt_pointer (snd_pcm_substream_t *);
@@ -1534,8 +1534,7 @@
/*
* Program PLX to allow interrupts */
-static __inline__ /* only used once */
-void pdplus_enable_interrupts_ll (pdplus_t *scard)
+static void pdplus_enable_interrupts_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -1549,8 +1548,7 @@
/*
* Read the contents of some PLX registers into the cache */
-static __inline__ /* only used once */
-void pdplus_read_initial_values_ll (pdplus_t *scard)
+static void pdplus_read_initial_values_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -1576,8 +1574,7 @@
/*
* **** ADC/DAC **** */
-static __inline__ /* without debug, this is very short */
-void pdplus_adda_write_ll (pdplus_t *scard, u_int reg, u_int value)
+static void pdplus_adda_write_ll (pdplus_t *scard, u_int reg, u_int value)
{
u_int regval;
PDPLUS_LOCAL_VADDR (scard);
@@ -1595,7 +1592,7 @@
* **** FPGA **** */
/*
* Clear interrupt status of cards */
-static __inline__ /* very short, should be fast */
+inline static /* very short, should be fast */
void pdplus_clear_interrupt_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -1983,6 +1980,7 @@
case 1:
ONE_CYCLE;
case 0:
+ ;
} while (cycle_count);
}
}
@@ -1993,8 +1991,7 @@
/*
* Write zero data into the card. */
-static __inline__ /* only used twice */
-void pdplus_write_silence_ll (
+static void pdplus_write_silence_ll (
vm_offset_t dst,
size_t byte_count)
@@ -2027,6 +2024,7 @@
case 1:
ONE_CYCLE;
case 0:
+ ;
} while (cycle_count);
}
return;
@@ -2248,7 +2246,7 @@
/*
* Stop analog play */
-static __inline__
+inline static
void pdplus_a_play_stop_ll (pdplus_t *scard)
{
/* Stop playing */
@@ -2261,7 +2259,7 @@
/*
* Stop analog capture */
-static __inline__
+inline static
void pdplus_a_capt_stop_ll (pdplus_t *scard)
{
/* Stop playing */
@@ -2274,7 +2272,7 @@
/*
* Stop digital play */
-static __inline__
+inline static
void pdplus_d_play_stop_ll (pdplus_t *scard)
{
/* Stop playing */
@@ -2287,7 +2285,7 @@
/*
* Stop digital capture */
-static __inline__
+inline static
void pdplus_d_capt_stop_ll (pdplus_t *scard)
{
/* Stop playing */
@@ -2300,7 +2298,7 @@
/*
* If ADAT monitoring is running, disable it. */
-static __inline__ /* very short */
+inline static
u_int pdplus_adat_mon_disable_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2314,7 +2312,7 @@
/*
* Set the flags to run adat monitoring. */
-static __inline__ /* very short */
+inline static
void pdplus_adat_mon_enable_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2346,7 +2344,7 @@
* I'm not sure yet, whether this will be needed. Why should one detach again?
* This is simply re-programming of the DCO, so simply keep it synched is ok? Is it?
*/
-static __inline__ /* very short */
+inline static
void __attribute__((__unused__)) pdplus_dco_detach_from_adat_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2369,7 +2367,7 @@
* The following function starts ADAT monitoring (full procedure).
* To restore ADAT monitoring that once worked, use
* pdplus_adat_mon_enable_ll*/
-static __inline__ /* very short */
+inline static
int pdplus_adat_mon_start_ll (pdplus_t *scard)
{
int err;
@@ -2384,7 +2382,7 @@
/*
* Stop adat monitoring (includes check for right mode) */
-static __inline__ /* very short */
+inline static
void pdplus_adat_mon_stop_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2523,7 +2521,7 @@
/*
* Look up the analog clock rate from the registers of the card. */
-static __inline__
+inline static
int pdplus_a_clock_rate_llr (pdplus_t *scard)
{
return pdplus_lookup_clock_llr (
@@ -2533,7 +2531,7 @@
/*
* Look up the digital clock rate from the registers of the card. */
-static __inline__
+inline static
int pdplus_d_clock_rate_llr (pdplus_t *scard)
{
return pdplus_lookup_clock_llr (
@@ -2544,7 +2542,7 @@
/*
* Switch back the digital output to normal mode */
-static __inline__ /* very short, only used twice */
+inline static
void pdplus_reset_d_route_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2560,7 +2558,7 @@
/*
* Switch back the analog output to normal mode */
-static __inline__ /* very short */
+inline static
void pdplus_reset_a_route_ll (pdplus_t *scard)
{
PDPLUS_LOCAL_VADDR (scard);
@@ -2645,7 +2643,7 @@
/*
* Check that neither the analog nor the digital device are malclocked.
* D_ROUTE must be safely set to D_PLAY and A_ROUTE to A_PLAY. */
-static __inline__ /* very short */
+inline static
void pdplus_check_clocks_ll (pdplus_t *scard)
{
pdplus_check_d_clock_ll (scard);
@@ -2893,7 +2891,7 @@
/* ********************************************************************** */
-static __inline__
+inline static
void pdplus_next_ring_ptr (pdplus_ring_ptr_t *ring_ptr)
{
ring_ptr->playing = (ring_ptr->playing + 1) & ring_ptr->mask;
@@ -3027,218 +3025,70 @@
/* ********************************************************************** */
/*
- * Prepare mode for playback (set period sizes, queuesizes, etc.) */
-#if 1
-#warning "This driver need to be ported to new hw_info"
-#else
-static int pdplus_set_up_mode (snd_pcm_substream_t *substream, BOOL is_adat,
- snd_pcm_hw_params_t *info)
+ * Hardware constraints for period size
+ */
+static int pdplus_hw_rule_period_size(snd_pcm_hw_params_t *hw,
+ snd_pcm_hw_rule_t *rule)
{
- int changed = 0, err;
- size_t tmp;
+ snd_interval_t *psize, *rate;
+ snd_interval_t newi;
- snd_assert (substream != NULL, return -ENXIO);
- snd_assert (substream->runtime != NULL, return -ENXIO);
+ psize = hw_param_interval(hw, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+ rate = hw_param_interval(hw, SNDRV_PCM_HW_PARAM_RATE);
+ snd_interval_any(&newi);
- /* Tell mid-level about period_size we want */
- tmp = pdplus_fit_period_size (
- info->period_size_min,
- is_adat,
- info->rate_min);
- if (info->period_size_min != tmp) {
- changed++;
- info->period_size_min = tmp;
- }
- tmp = pdplus_fit_period_size (
- info->period_size_max,
- is_adat,
- info->rate_max);
- if (info->period_size_max == tmp) {
- changed++;
- info->period_size_max = tmp;
- }
+ newi.min = pdplus_fit_period_size (psize->min, is_adat, rate->min);
+ newi.max = pdplus_fit_period_size (psize->max, is_adat, rate->max);
- /* Have the structure filled in */
- err = snd_pcm_hw_info_buffer_size_max (info,
- PDPLUS_FRAMES_FROM_BYTES(
- PDPLUS_BUFFER_SIZE,
- is_adat));
- if (err < 0)
- return err;
- changed += err;
-
- return changed;
-}
-#endif
-
-/*
- * Ioctl functions */
-static int pdplus_a_ioctl (snd_pcm_substream_t *substream, u_int cmd, void *arg)
-{
- snd_assert (substream != NULL, return -ENXIO);
- snd_assert (substream->runtime != NULL, return -ENXIO);
-
-#if 1
-#warning "This driver need to be ported to new hw_info"
-#else
- if (cmd == SNDRV_PCM_IOCTL1_HW_INFO) {
- snd_pcm_hw_params_t *info = arg;
- int changed = 0, err;
-
- if ((err = pdplus_set_up_mode (substream, is_adat, info)) < 0)
- return err;
- changed += err;
- if ((err = snd_pcm_hw_info_generic(info, substream)) < 0)
- return err;
- changed += err;
- return changed;
- }
-#endif
- return snd_pcm_lib_ioctl (substream, cmd, arg);
+ return snd_interval_refine(psize, &newi);
}
-static int pdplus_d_play_ioctl (snd_pcm_substream_t *substream, u_int cmd, void *arg)
+/*
+ * hw constraint for rate on the digital playback
+ */
+static int pdplus_d_play_hw_rule_rate(snd_pcm_hw_params_t *hw,
+ snd_pcm_hw_rule_t *rule)
{
- snd_assert (substream != NULL, return -ENXIO);
- snd_assert (substream->runtime != NULL, return -ENXIO);
-
-#if 1
-#warning "This driver need to be ported to new hw_info"
-#else
- if (cmd == SNDRV_PCM_IOCTL1_HW_INFO) {
- snd_pcm_hw_params_t *info = arg;
- int changed = 0, err;
#if IEC958_ALLOW_HIGH_FREQ
- int const profi = 1;
-#else
- pdplus_t *scard = snd_pcm_substream_chip(substream);
- int profi = (scard->profi_mode || scard->auto_profi_mode);
- if (!always_profi) {
- u_char *cs = pdplus_get_channel_status (scard);
- if (cs != NULL)
- profi = cs[0] & IEC958_AES0_PROFESSIONAL;
- }
-#endif
- if ((err = snd_pcm_hw_info_rate_list(info, profi ? 5 : 3, d_rate_llr))
< 0)
- return err;
- changed += err;
- if ((err = pdplus_set_up_mode (substream, is_adat, info)) < 0)
- return err;
- changed += err;
- if ((err = snd_pcm_hw_info_generic(info, substream)) < 0)
- return err;
- changed += err;
- return changed;
- } else
-#endif
-#if 1
-#warning "The S/PDIF setup code needs to be rewritten."
+ int const profi = 1;
#else
- if (cmd == SNDRV_PCM_IOCTL1_DIG_INFO) {
- pdplus_t *scard = snd_pcm_substream_chip(substream);
- snd_pcm_dig_info_t *info = arg;
- if (info->group != 0) {
- info->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_GROUP;
- return -EINVAL;
- }
- info->type_mask = SNDRV_PCM_DIG_AES_IEC958C |
- SNDRV_PCM_DIG_AES_IEC958P;
- if (info->type == SNDRV_PCM_DIG_NONE)
- return 0;
- info->mask.aes.status[0] = IEC958_AES0_PROFESSIONAL |
- IEC958_AES0_NONAUDIO;
- if (info->type == SNDRV_PCM_DIG_AES_IEC958C) {
- info->mask.aes.status[0] |=
- IEC958_AES0_CON_NOT_COPYRIGHT |
- IEC958_AES0_CON_EMPHASIS;
- info->mask.aes.status[1] =
- IEC958_AES1_CON_CATEGORY;
- info->mask.aes.status[3] =
- IEC958_AES3_CON_FS;
- if (!(scard->dig_setup.aes.status[0] &
IEC958_AES0_PROFESSIONAL))
- info->val = scard->dig_setup;
- } else if (info->type == SNDRV_PCM_DIG_AES_IEC958P) {
- info->mask.aes.status[0] |=
- IEC958_AES0_PRO_FS |
- IEC958_AES0_PRO_EMPHASIS;
- if (scard->dig_setup.aes.status[0] & IEC958_AES0_PROFESSIONAL)
- info->val = scard->dig_setup;
- else
- info->val.aes.status[0] |= IEC958_AES0_PROFESSIONAL;
- } else {
- info->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_TYPE;
- return -EINVAL;
- }
- return 0;
- } else if (cmd == SNDRV_PCM_IOCTL1_DIG_PARAMS) {
- pdplus_t *scard = snd_pcm_substream_chip(substream);
- snd_pcm_dig_params_t *params = arg;
- if (params->group != 0) {
- params->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_GROUP;
- return -EINVAL;
- }
- if (params->type == SNDRV_PCM_DIG_AES_IEC958C) {
- if (params->val.aes.status[0] & IEC958_AES0_PROFESSIONAL) {
- params->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_VALUE;
- return -EINVAL;
- }
- scard->dig_setup = params->val;
- } else if (params->type == SNDRV_PCM_DIG_AES_IEC958P) {
- if (!(params->val.aes.status[0] & IEC958_AES0_PROFESSIONAL)) {
- params->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_VALUE;
- return -EINVAL;
- }
- scard->dig_setup = params->val;
- } else {
- params->fail_mask = 1 << SNDRV_PCM_DIG_PARAM_TYPE;
- return -EINVAL;
- }
- /* FIXME: digital parameters should be updated only here */
- return 0;
+ pdplus_t *scard = snd_magic_cast(pdplus_t, rule->private, return -EINVAL);
+ int profi = (scard->profi_mode || scard->auto_profi_mode);
+ if (!always_profi) {
+ u_char *cs = pdplus_get_channel_status (scard);
+ if (cs != NULL)
+ profi = cs[0] & IEC958_AES0_PROFESSIONAL;
}
#endif
- return snd_pcm_lib_ioctl (substream, cmd, arg);
+ return snd_interval_list(hw_param_interval(hw, SNDRV_PCM_HW_PARAM_RATE),
+ profi ? 5 : 3, d_rate_llr, 0);
}
-static int pdplus_d_capt_ioctl (snd_pcm_substream_t *substream, u_int cmd, void *arg)
+/*
+ * hw constraint for rate on the digital capture
+ */
+static int pdplus_d_capt_hw_rule_rate(snd_pcm_hw_params_t *hw,
+ snd_pcm_hw_rule_t *rule)
{
- pdplus_t *scard = snd_pcm_substream_chip(substream);
-
- snd_assert (substream != NULL, return -ENXIO);
- snd_assert (substream->runtime != NULL, return -ENXIO);
+ pdplus_t *scard = snd_magic_cast(pdplus_t, rule->private, return -EINVAL);
+ int rate;
+ unsigned long flags;
+ snd_interval_t newi;
+
+ /* Force synchronised rate */
+ read_lock_irqsave (&scard->lock, flags);
+ rate = pdplus_d_capt_rate_llr (scard);
+ read_unlock_irqrestore (&scard->lock, flags);
+ if (rate <= 0)
+ return 0; /* FIXME: should return the error? */
+ snd_interval_any(&newi);
+ newi.min = newi.max = rate;
-#if 1
-#warning "This driver need to be ported to new hw_info"
-#else
- if (cmd == SNDRV_PCM_IOCTL1_HW_INFO) {
- snd_pcm_hw_params_t *info = arg;
- int changed = 0, err, rate;
- unsigned long flags;
-
- /* Force synchronised rate */
- read_lock_irqsave (&scard->lock, flags);
- rate = pdplus_d_capt_rate_llr (scard);
- read_unlock_irqrestore (&scard->lock, flags);
- if (rate <= 0)
- LEAVE (-EIO); /* FIXME:CHECK: is this the correct error code?
*/
- if (rate != info->rate_min)
- changed++;
- if (rate != info->rate_max)
- changed++;
- info->rate_min = info->rate_max = rate;
- if ((err = pdplus_set_up_mode (substream, is_adat, info)) < 0)
- return err;
- changed += err;
- if ((err = snd_pcm_hw_info_generic(info, substream)) < 0)
- return err;
- changed += err;
- return changed;
- }
-#endif
- return snd_pcm_lib_ioctl (substream, cmd, arg);
+ return snd_interval_refine(hw_param_interval(hw,
+SNDRV_PCM_HW_PARAM_PERIOD_SIZE), &newi);
}
+
/*
* Get the buffer pointer for analog playback */
static snd_pcm_uframes_t pdplus_a_play_pointer (snd_pcm_substream_t *substream)
@@ -3912,16 +3762,16 @@
static snd_pcm_hardware_t pdplus_a_play_info =
{
- info:
+ .info =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_SYNC_START,
- /* SNDRV_PCM_INFO_BLOCK_TRANSFER | FIXME: what is this? */
- formats:
+ .formats =
SNDRV_PCM_FMTBIT_S24_LE,
- rates: /* DCO Frequency Generator: */
+ .rates = /* DCO Frequency Generator: */
SNDRV_PCM_RATE_CONTINUOUS |
/* Fixed Frequency Generator: */
SNDRV_PCM_RATE_48000 |
@@ -3930,36 +3780,36 @@
SNDRV_PCM_RATE_22050 |
SNDRV_PCM_RATE_11025,
- rate_min: 11025, /* min: FFG only, DCO starts at 29000, ADC/DAC could do
4kHz */
- rate_max: 50000, /* max: 50kHz for ADC/DAC according to CS4222
specification. */
-
- channels_min: 2,
- channels_max: 2,
-
- buffer_bytes_max: PDPLUS_BUFFER_SIZE,
-
- period_bytes_min: PDPLUS_SMALL_BLOCK, /* this depends on the sampling rate.
*/
- period_bytes_max: PDPLUS_LARGE_BLOCK,
-
- periods_min: 1,
- periods_max: 1024,
- fifo_size: 0,
+ .rate_min = 11025, /* min: FFG only, DCO starts at 29000, ADC/DAC could do
+4kHz */
+ .rate_max = 50000, /* max: 50kHz for ADC/DAC according to CS4222
+specification. */
+
+ .channels_min = 2,
+ .channels_max = 2,
+
+ .buffer_bytes_max = PDPLUS_BUFFER_SIZE,
+
+ .period_bytes_min = PDPLUS_SMALL_BLOCK, /* this depends on the sampling
+rate. */
+ .period_bytes_max = PDPLUS_LARGE_BLOCK,
+
+ .periods_min = 1,
+ .periods_max = 1024,
+ .fifo_size = 0,
};
/* ********************************************************************** */
static snd_pcm_hardware_t pdplus_a_capt_info =
{
- info:
+ .info =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_SYNC_START,
- /* SNDRV_PCM_INFO_BLOCK_TRANSFER | FIXME: what is this? */
- formats:
+ .formats =
SNDRV_PCM_FMTBIT_S24_LE,
- rates: /* DCO Frequency Generator: */
+ .rates = /* DCO Frequency Generator: */
SNDRV_PCM_RATE_CONTINUOUS |
/* Fixed Frequency Generator: */
SNDRV_PCM_RATE_48000 |
@@ -3968,72 +3818,72 @@
SNDRV_PCM_RATE_22050 |
SNDRV_PCM_RATE_11025,
- rate_min: 11025, /* min: FFG only, DCO starts at 29000, ADC/DAC could do
4kHz */
- rate_max: 50000, /* max: 50kHz for ADC/DAC according to CS4222
specification. */
-
- channels_min: 2,
- channels_max: 2,
-
- buffer_bytes_max: PDPLUS_BUFFER_SIZE,
-
- period_bytes_min: PDPLUS_SMALL_BLOCK, /* this depends on the sampling rate.
*/
- period_bytes_max: PDPLUS_LARGE_BLOCK,
-
- periods_min: 1,
- periods_max: 1024,
- fifo_size: 0,
+ .rate_min = 11025, /* min: FFG only, DCO starts at 29000, ADC/DAC could do
+4kHz */
+ .rate_max = 50000, /* max: 50kHz for ADC/DAC according to CS4222
+specification. */
+
+ .channels_min = 2,
+ .channels_max = 2,
+
+ .buffer_bytes_max = PDPLUS_BUFFER_SIZE,
+
+ .period_bytes_min = PDPLUS_SMALL_BLOCK, /* this depends on the sampling
+rate. */
+ .period_bytes_max = PDPLUS_LARGE_BLOCK,
+
+ .periods_min = 1,
+ .periods_max = 1024,
+ .fifo_size = 0,
};
/* ********************************************************************** */
static snd_pcm_hardware_t pdplus_d_play_info =
{
- info:
+ .info =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_SYNC_START,
- /* SNDRV_PCM_INFO_BLOCK_TRANSFER | FIXME: what is this? */
- formats:
+ .formats =
SNDRV_PCM_FMTBIT_S24_LE,
- rates: /* Fixed Frequency Generator: */
+ .rates = /* Fixed Frequency Generator: */
SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_32000,
- rate_min: 32000,
- rate_max: 96000,
+ .rate_min = 32000,
+ .rate_max = 96000,
- channels_min: 2,
- channels_max: 2,
+ .channels_min = 2,
+ .channels_max = 2,
- buffer_bytes_max: PDPLUS_BUFFER_SIZE,
+ .buffer_bytes_max = PDPLUS_BUFFER_SIZE,
- period_bytes_min: PDPLUS_SMALL_BLOCK, /* this depends on the sampling rate.
*/
- period_bytes_max: PDPLUS_LARGE_BLOCK,
+ .period_bytes_min = PDPLUS_SMALL_BLOCK, /* this depends on the sampling
+rate. */
+ .period_bytes_max = PDPLUS_LARGE_BLOCK,
- periods_min: 1,
- periods_max: 1024,
- fifo_size: 0,
+ .periods_min = 1,
+ .periods_max = 1024,
+ .fifo_size = 0,
};
/* ********************************************************************** */
static snd_pcm_hardware_t pdplus_d_capt_info =
{
- info:
+ .info =
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_SYNC_START,
- /* SNDRV_PCM_INFO_BLOCK_TRANSFER | FIXME: what is this? */
- formats:
+ .formats =
SNDRV_PCM_FMTBIT_S24_LE,
- rates:
+ .rates =
/* This can synchronise to those frequencies (this cannot be
* set, though): */
SNDRV_PCM_RATE_96000 |
@@ -4042,20 +3892,20 @@
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_32000,
- rate_min: 32000,
- rate_max: 96000,
+ .rate_min = 32000,
+ .rate_max = 96000,
- channels_min: 2,
- channels_max: 2,
+ .channels_min = 2,
+ .channels_max = 2,
- buffer_bytes_max: PDPLUS_BUFFER_SIZE,
+ .buffer_bytes_max = PDPLUS_BUFFER_SIZE,
- period_bytes_min: PDPLUS_SMALL_BLOCK, /* this depends on the sampling rate.
*/
- period_bytes_max: PDPLUS_LARGE_BLOCK,
+ .period_bytes_min = PDPLUS_SMALL_BLOCK, /* this depends on the sampling
+rate. */
+ .period_bytes_max = PDPLUS_LARGE_BLOCK,
- periods_min: 1,
- periods_max: 1024,
- fifo_size: 0,
+ .periods_min = 1,
+ .periods_max = 1024,
+ .fifo_size = 0,
};
/* ********************************************************************** */
@@ -4065,17 +3915,28 @@
static int pdplus_a_play_open (snd_pcm_substream_t *substream)
{
u_long flags;
+ int err;
pdplus_t *scard = snd_pcm_substream_chip(substream);
ENTER;
snd_assert (substream != NULL, return -ENXIO);
snd_assert (substream->runtime != NULL, return -ENXIO);
+ substream->runtime->hw = pdplus_a_play_info;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ pdplus_hw_rule_period_size, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
snd_pcm_set_sync (substream);
write_lock_irqsave (&scard->lock, flags);
scard->a_play = substream;
- substream->runtime->hw = pdplus_a_play_info;
write_unlock_irqrestore (&scard->lock, flags);
@@ -4111,17 +3972,28 @@
static int pdplus_a_capt_open (snd_pcm_substream_t *substream)
{
u_long flags;
+ int err;
pdplus_t *scard = snd_pcm_substream_chip(substream);
ENTER;
snd_assert (substream != NULL, return -ENXIO);
snd_assert (substream->runtime != NULL, return -ENXIO);
+ substream->runtime->hw = pdplus_a_capt_info;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ pdplus_hw_rule_period_size, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
snd_pcm_set_sync (substream);
write_lock_irqsave (&scard->lock, flags);
scard->a_capt = substream;
- substream->runtime->hw = pdplus_a_capt_info;
write_unlock_irqrestore (&scard->lock, flags);
@@ -4187,14 +4059,30 @@
if ((err = pdplus_set_mode (scard, PDPLUS_MODE_DIGITAL)))
LEAVE (err);
+ substream->runtime->hw = pdplus_d_play_info;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ pdplus_d_play_hw_rule_rate, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ pdplus_hw_rule_period_size, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
+
snd_pcm_set_sync (substream);
write_lock_irqsave (&scard->lock, flags);
scard->d_play = substream;
- substream->runtime->hw = pdplus_d_play_info;
-
write_unlock_irqrestore (&scard->lock, flags);
LEAVE (0);
@@ -4234,12 +4122,29 @@
if ((err = pdplus_set_mode (scard, PDPLUS_MODE_DIGITAL)))
LEAVE (err);
+ substream->runtime->hw = pdplus_d_capt_info;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ pdplus_d_capt_hw_rule_rate, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_rule_add(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ pdplus_hw_rule_period_size, scard,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+ if (err < 0)
+ return err;
+ err = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (err < 0)
+ return err;
+
snd_pcm_set_sync (substream);
write_lock_irqsave (&scard->lock, flags);
scard->d_capt = substream;
- substream->runtime->hw = pdplus_d_capt_info;
write_unlock_irqrestore (&scard->lock, flags);
@@ -4269,45 +4174,45 @@
/* ********************************************************************** */
static snd_pcm_ops_t pdplus_a_play_ops = {
- open: pdplus_a_play_open,
- close: pdplus_a_play_close,
- ioctl: pdplus_a_ioctl,
- prepare: pdplus_a_play_prepare,
- trigger: pdplus_a_play_trigger,
- pointer: pdplus_a_play_pointer,
- copy: pdplus_a_play_copy_ll,
- silence: pdplus_a_play_silence_ll,
+ .open = pdplus_a_play_open,
+ .close = pdplus_a_play_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = pdplus_a_play_prepare,
+ .trigger = pdplus_a_play_trigger,
+ .pointer = pdplus_a_play_pointer,
+ .copy = pdplus_a_play_copy_ll,
+ .silence = pdplus_a_play_silence_ll,
};
static snd_pcm_ops_t pdplus_a_capt_ops = {
- open: pdplus_a_capt_open,
- close: pdplus_a_capt_close,
- ioctl: pdplus_a_ioctl,
- prepare: pdplus_a_capt_prepare,
- trigger: pdplus_a_capt_trigger,
- pointer: pdplus_a_capt_pointer,
- copy: pdplus_a_capt_copy_ll,
+ .open = pdplus_a_capt_open,
+ .close = pdplus_a_capt_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = pdplus_a_capt_prepare,
+ .trigger = pdplus_a_capt_trigger,
+ .pointer = pdplus_a_capt_pointer,
+ .copy = pdplus_a_capt_copy_ll,
};
static snd_pcm_ops_t pdplus_d_play_ops = {
- open: pdplus_d_play_open,
- close: pdplus_d_play_close,
- ioctl: pdplus_d_play_ioctl,
- prepare: pdplus_d_play_prepare,
- trigger: pdplus_d_play_trigger,
- pointer: pdplus_d_play_pointer,
- copy: pdplus_d_play_copy_ll,
- silence: pdplus_d_play_silence_ll,
+ .open = pdplus_d_play_open,
+ .close = pdplus_d_play_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = pdplus_d_play_prepare,
+ .trigger = pdplus_d_play_trigger,
+ .pointer = pdplus_d_play_pointer,
+ .copy = pdplus_d_play_copy_ll,
+ .silence = pdplus_d_play_silence_ll,
};
static snd_pcm_ops_t pdplus_d_capt_ops = {
- open: pdplus_d_capt_open,
- close: pdplus_d_capt_close,
- ioctl: pdplus_d_capt_ioctl,
- prepare: pdplus_d_capt_prepare,
- trigger: pdplus_d_capt_trigger,
- pointer: pdplus_d_capt_pointer,
- copy: pdplus_d_capt_copy_ll,
+ .open = pdplus_d_capt_open,
+ .close = pdplus_d_capt_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .prepare = pdplus_d_capt_prepare,
+ .trigger = pdplus_d_capt_trigger,
+ .pointer = pdplus_d_capt_pointer,
+ .copy = pdplus_d_capt_copy_ll,
};
/* ********************************************************************** */
@@ -4326,7 +4231,7 @@
/* ********************************************************************** */
-static __init int pdplus_a_pcm_new (
+static __devinit int pdplus_a_pcm_new (
snd_card_t *card,
pdplus_t *scard,
int device)
@@ -4359,7 +4264,7 @@
LEAVE (0);
}
-static __init int pdplus_d_pcm_new (
+static __devinit int pdplus_d_pcm_new (
snd_card_t *card,
pdplus_t *scard,
int device)
@@ -4394,22 +4299,22 @@
/* ********************************************************************** */
/* Mixer functions */
-static __inline__ int pdplus_adda_get_volume_left_llr (pdplus_t *scard)
+inline static int pdplus_adda_get_volume_left_llr (pdplus_t *scard)
{
return PDPLUS_CS4222_ATTEN_MAX - PDPLUS_READ_CACHE (scard, CS4222, ATT_LEFT);
}
-static __inline__ int pdplus_adda_get_volume_right_llr (pdplus_t *scard)
+inline static int pdplus_adda_get_volume_right_llr (pdplus_t *scard)
{
return PDPLUS_CS4222_ATTEN_MAX - PDPLUS_READ_CACHE (scard, CS4222, ATT_RIGHT);
}
-static __inline__ void pdplus_adda_set_volume_left_ll (pdplus_t *scard, int value)
+inline static void pdplus_adda_set_volume_left_ll (pdplus_t *scard, int value)
{
PDPLUS_WRITE (scard, CS4222, ATT_LEFT, PDPLUS_CS4222_ATTEN_MAX - value);
}
-static __inline__ void pdplus_adda_set_volume_right_ll (pdplus_t *scard, int value)
+inline static void pdplus_adda_set_volume_right_ll (pdplus_t *scard, int value)
{
PDPLUS_WRITE (scard, CS4222, ATT_RIGHT, PDPLUS_CS4222_ATTEN_MAX - value);
}
@@ -4423,12 +4328,12 @@
*/
#define PDPLUS_CONTROL_DAC_VOLUME \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "PCM Playback Volume", \
- index: 0, \
- info: pdplus_dac_volume_info, \
- get: pdplus_dac_volume_get, \
- put: pdplus_dac_volume_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "PCM Playback Volume", \
+ .index = 0, \
+ .info = pdplus_dac_volume_info, \
+ .get = pdplus_dac_volume_get, \
+ .put = pdplus_dac_volume_set \
}
static int pdplus_dac_volume_info (snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
@@ -4478,12 +4383,12 @@
#define PDPLUS_CONTROL_DAC_SWITCH \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "PCM Playback Switch", \
- index: 0, \
- info: pdplus_boolean2_info, \
- get: pdplus_dac_switch_get, \
- put: pdplus_dac_switch_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "PCM Playback Switch", \
+ .index = 0, \
+ .info = pdplus_boolean2_info, \
+ .get = pdplus_dac_switch_get, \
+ .put = pdplus_dac_switch_set \
}
static int pdplus_dac_switch_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -4528,12 +4433,12 @@
#define PDPLUS_CONTROL_ADC_SWITCH \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "Analog Capture Switch", \
- index: 0, \
- info: pdplus_boolean2_info, \
- get: pdplus_adc_switch_get, \
- put: pdplus_adc_switch_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Analog Capture Switch", \
+ .index = 0, \
+ .info = pdplus_boolean2_info, \
+ .get = pdplus_adc_switch_get, \
+ .put = pdplus_adc_switch_set \
}
static int pdplus_adc_switch_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -4578,12 +4483,12 @@
#define PDPLUS_CONTROL_ADC_HIGH_PASS \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "Analog Capture High Pass Filter", \
- index: 0, \
- info: pdplus_boolean2_info, \
- get: pdplus_adc_high_pass_get, \
- put: pdplus_adc_high_pass_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Analog Capture High Pass Filter", \
+ .index = 0, \
+ .info = pdplus_boolean2_info, \
+ .get = pdplus_adc_high_pass_get, \
+ .put = pdplus_adc_high_pass_set \
}
static int pdplus_boolean2_info (snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
@@ -4637,12 +4542,12 @@
#define PDPLUS_CONTROL_DAC_AUTO_MUTE_512 \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "PCM Playback Auto Mute 512", \
- index: 0, \
- info: pdplus_boolean1_info, \
- get: pdplus_dac_auto_mute_512_get, \
- put: pdplus_dac_auto_mute_512_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "PCM Playback Auto Mute 512", \
+ .index = 0, \
+ .info = pdplus_boolean1_info, \
+ .get = pdplus_dac_auto_mute_512_get, \
+ .put = pdplus_dac_auto_mute_512_set \
}
static int pdplus_boolean1_info (snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
@@ -4688,12 +4593,12 @@
#define PDPLUS_CONTROL_A_OUT_MUX \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "Analog Output Select", \
- index: 0, \
- info: pdplus_out_mux_info, \
- get: pdplus_a_out_mux_get, \
- put: pdplus_a_out_mux_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Analog Output Select", \
+ .index = 0, \
+ .info = pdplus_out_mux_info, \
+ .get = pdplus_a_out_mux_get, \
+ .put = pdplus_a_out_mux_set \
}
static void pdplus_info_enumerated (
@@ -4763,12 +4668,12 @@
#define PDPLUS_CONTROL_D_OUT_MUX \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "Digital Output Select", \
- index: 0, \
- info: pdplus_out_mux_info, \
- get: pdplus_d_out_mux_get, \
- put: pdplus_d_out_mux_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Digital Output Select", \
+ .index = 0, \
+ .info = pdplus_out_mux_info, \
+ .get = pdplus_d_out_mux_get, \
+ .put = pdplus_d_out_mux_set \
}
static int pdplus_d_out_mux_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -4804,12 +4709,12 @@
#define PDPLUS_CONTROL_D_IN_MUX \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "Digital Input Select", \
- index: 0, \
- info: pdplus_in_mux_info, \
- get: pdplus_d_in_mux_get, \
- put: pdplus_d_in_mux_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Digital Input Select", \
+ .index = 0, \
+ .info = pdplus_in_mux_info, \
+ .get = pdplus_d_in_mux_get, \
+ .put = pdplus_d_in_mux_set \
}
static char const *pdplus_in_mux_text[3]= {
@@ -4859,12 +4764,12 @@
#define PDPLUS_CONTROL_DE_EMPH \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_PCM, \
- name: "Codec De-Emphasis 50/15", \
- index: 0, \
- info: pdplus_de_emph_info, \
- get: pdplus_de_emph_get, \
- put: pdplus_de_emph_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
+ .name= "Codec De-Emphasis 50/15", \
+ .index = 0, \
+ .info = pdplus_de_emph_info, \
+ .get = pdplus_de_emph_get, \
+ .put = pdplus_de_emph_set \
}
static char const *pdplus_de_emph_text[4]= {
@@ -4917,12 +4822,12 @@
#define PDPLUS_CONTROL_DAC_SOFT_RAMP \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_MIXER, \
- name: "PCM Playback Volume Soft Ramping", \
- index: 0, \
- info: pdplus_soft_ramp_info, \
- get: pdplus_soft_ramp_get, \
- put: pdplus_soft_ramp_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "PCM Playback Volume Soft Ramping", \
+ .index = 0, \
+ .info = pdplus_soft_ramp_info, \
+ .get = pdplus_soft_ramp_get, \
+ .put = pdplus_soft_ramp_set \
}
#define PDPLUS_SOFT_RAMP_OFF 4
@@ -4991,10 +4896,10 @@
#define PDPLUS_CONTROL_D_CAPT_RATE \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_HWDEP, \
- name: "Digital Input Clock", \
- index: 0, \
- access: SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Digital Input Clock", \
+ .index = 0, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
info: pdplus_d_capt_rate_info, \
get: pdplus_d_capt_rate_get, \
put: NULL \
@@ -5023,12 +4928,12 @@
#define PDPLUS_CONTROL_DEF_PROFI_MODE \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_CARD, \
- name: "Default Digital Format", \
- index: 0, \
- info: pdplus_def_profi_mode_info, \
- get: pdplus_def_profi_mode_get, \
- put: pdplus_def_profi_mode_set, \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Default Digital Format", \
+ .index = 0, \
+ .info = pdplus_def_profi_mode_info, \
+ .get = pdplus_def_profi_mode_get, \
+ .put = pdplus_def_profi_mode_set, \
}
static int pdplus_def_profi_mode_info (snd_kcontrol_t *k, snd_ctl_elem_info_t *u)
@@ -5100,12 +5005,12 @@
#define PDPLUS_CONTROL_DEF_COPY_INHIBIT \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_CARD, \
- name: "Default Copy Inhibit", \
- index: 0, \
- info: pdplus_boolean1_info, \
- get: pdplus_def_copy_inhibit_get, \
- put: pdplus_def_copy_inhibit_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Default Copy Inhibit", \
+ .index = 0, \
+ .info = pdplus_boolean1_info, \
+ .get = pdplus_def_copy_inhibit_get, \
+ .put = pdplus_def_copy_inhibit_set \
}
static int pdplus_def_copy_inhibit_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -5136,12 +5041,12 @@
#define PDPLUS_CONTROL_DEF_NON_AUDIO \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_CARD, \
- name: "Default Non-Audio Bit", \
- index: 0, \
- info: pdplus_boolean1_info, \
- get: pdplus_def_non_audio_get, \
- put: pdplus_def_non_audio_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Default Non-Audio Bit", \
+ .index = 0, \
+ .info = pdplus_boolean1_info, \
+ .get = pdplus_def_non_audio_get, \
+ .put = pdplus_def_non_audio_set \
}
static int pdplus_def_non_audio_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -5172,12 +5077,12 @@
#define PDPLUS_CONTROL_DEF_PRE_EMPHASIS \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_CARD, \
- name: "Default Pre-Emphasis", \
- index: 0, \
- info: pdplus_boolean1_info, \
- get: pdplus_def_pre_emphasis_get, \
- put: pdplus_def_pre_emphasis_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Default Pre-Emphasis", \
+ .index = 0, \
+ .info = pdplus_boolean1_info, \
+ .get = pdplus_def_pre_emphasis_get, \
+ .put = pdplus_def_pre_emphasis_set \
}
static int pdplus_def_pre_emphasis_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -5208,12 +5113,12 @@
#define PDPLUS_CONTROL_DEF_AUTO_CD_MODE \
{ \
- iface: SNDRV_CTL_ELEM_IFACE_CARD, \
- name: "Default Auto CD Mode", \
- index: 0, \
- info: pdplus_boolean1_info, \
- get: pdplus_def_auto_cd_mode_get, \
- put: pdplus_def_auto_cd_mode_set \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Default Auto CD Mode", \
+ .index = 0, \
+ .info = pdplus_boolean1_info, \
+ .get = pdplus_def_auto_cd_mode_get, \
+ .put = pdplus_def_auto_cd_mode_set \
}
static int pdplus_def_auto_cd_mode_get (snd_kcontrol_t *k, snd_ctl_elem_value_t *u)
@@ -5242,7 +5147,68 @@
return result;
}
-static snd_kcontrol_new_t pdplus_control[]= {
+/*
+ * S/PDIF set up
+ */
+static int pdplus_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *
+uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int pdplus_spdif_cmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *
+ucontrol)
+{
+ ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
+ IEC958_AES0_NONAUDIO |
+ IEC958_AES0_CON_NOT_COPYRIGHT |
+ IEC958_AES0_CON_EMPHASIS;
+ ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY;
+ ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
+ return 0;
+}
+
+static int pdplus_spdif_pmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *
+ucontrol)
+{
+ ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
+ IEC958_AES0_NONAUDIO |
+ IEC958_AES0_PRO_FS |
+ IEC958_AES0_PRO_EMPHASIS;
+ return 0;
+}
+
+static int pdplus_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *
+ucontrol)
+{
+ pdplus_t *scard = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
+
+ read_lock_irqsave(&scard->lock, flags);
+ ucontrol->value.iec958 = scard->dig_setup;
+ read_unlock_irqrestore(&scard->lock, flags);
+ return 0;
+}
+
+static int pdplus_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *
+ucontrol)
+{
+ pdplus_t *scard = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
+ int change;
+
+ write_lock_irqsave(&scard->lock, flags);
+ if (memcmp(&ucontrol->value.iec958, &scard->dig_setup,
+sizeof(scard->dig_setup)) == 0)
+ change = 0;
+ else {
+ scard->dig_setup = ucontrol->value.iec958;
+ change = 1;
+ }
+ write_unlock_irqrestore(&scard->lock, flags);
+ return change;
+}
+
+/*
+ * entries
+ */
+static snd_kcontrol_new_t pdplus_control[] __devinitdata = {
PDPLUS_CONTROL_DAC_VOLUME,
PDPLUS_CONTROL_DAC_SWITCH,
PDPLUS_CONTROL_DAC_AUTO_MUTE_512,
@@ -5259,13 +5225,35 @@
PDPLUS_CONTROL_DEF_COPY_INHIBIT,
PDPLUS_CONTROL_DEF_NON_AUDIO,
PDPLUS_CONTROL_DEF_AUTO_CD_MODE,
- PDPLUS_CONTROL_DEF_PRE_EMPHASIS
+ PDPLUS_CONTROL_DEF_PRE_EMPHASIS,
+
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+ .info = pdplus_spdif_mask_info,
+ .get = pdplus_spdif_cmask_get,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+ .info = pdplus_spdif_mask_info,
+ .get = pdplus_spdif_pmask_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .info = pdplus_spdif_mask_info,
+ .get = pdplus_spdif_default_get,
+ .put = pdplus_spdif_default_put,
+ },
};
-#define PDPLUS_CONTROL_CNT (sizeof (pdplus_control) / sizeof(pdplus_control[0]))
+#define PDPLUS_CONTROL_CNT ARRAY_SIZE(pdplus_control)
/* New mixer */
-static int __init pdplus_mixer_new (pdplus_t *scard)
+static int __devinit pdplus_mixer_new (pdplus_t *scard)
{
snd_card_t *card;
snd_kcontrol_t *k;
@@ -5797,51 +5785,22 @@
/*
* Register the /proc entry */
-static void __init pdplus_register_proc (pdplus_t *scard)
+static void __devinit pdplus_register_proc (pdplus_t *scard)
{
snd_info_entry_t *entry;
snd_assert (scard != NULL, return);
snd_assert (scard->card != NULL, return);
- if ((entry = snd_info_create_card_entry (scard->card, "prodif_plus",
scard->card->proc_root)) != NULL) {
- entry->content = SNDRV_INFO_CONTENT_TEXT;
- entry->private_data = (void*)scard;
- entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-#if DEBUG
- entry->c.text.read_size = 65536;
-#else
- entry->c.text.read_size = 1024;
-#endif
- entry->c.text.read = pdplus_proc_read;
- if (snd_info_register (entry) < 0) {
- snd_info_free_entry (entry);
- entry = NULL;
- return;
- }
- }
-
- scard->proc_entry = entry;
-}
-
-
-/*
- * Unregister the /proc entry */
-static void __exit pdplus_unregister_proc (pdplus_t *scard)
-{
- snd_assert (scard != NULL, return);
-
- if (scard->proc_entry) {
- snd_info_unregister (scard->proc_entry);
- scard->proc_entry = NULL;
- }
+ if (! snd_card_proc_new (scard->card, "prodif_plus", &entry))
+ snd_info_set_text_ops(entry, scard, pdplus_proc_read);
}
/*
* Check that the resource queries of the card are sane */
#if MANY_CHECKS
-static int __init pdplus_check_resources (pci_dev_t *pci)
+static int __devinit pdplus_check_resources (pci_dev_t *pci)
{
u_long x;
@@ -5901,7 +5860,7 @@
/*
* Register memory area */
-static int __init pdplus_register_iomem (
+static int __devinit pdplus_register_iomem (
snd_card_t *card,
pci_dev_t *pci,
int num,
@@ -5938,7 +5897,7 @@
#if CHECK
/*
* Check consistency of some aspects of the card. */
-static int __init pdplus_check_consistency_ll (pdplus_t *scard)
+static int __devinit pdplus_check_consistency_ll (pdplus_t *scard)
{
u32 x, y;
PDPLUS_LOCAL_VADDR (scard);
@@ -5981,7 +5940,7 @@
* are not easy to have here. Furthermore, check that all called functions
* only use the vaddrs known at the time of calling!! (ht)
*/
-static int __init pdplus_init(
+static int __devinit pdplus_init(
pci_dev_t *pci,
snd_card_t *card)
{
@@ -5995,9 +5954,6 @@
if (scard == NULL)
LEAVE (-ENOMEM);
-#if DEBUG
- scard->magic = pdplus_t_magic;
-#endif
scard->pci = pci;
scard->card = card;
@@ -6005,7 +5961,7 @@
/* *INIT* */
scard->a_out_route = PDPLUS_ROUTE_A_PLAY;
scard->d_out_route = PDPLUS_ROUTE_D_PLAY;
- scard->lock = RW_LOCK_UNLOCKED;
+ rwlock_init(&scard->lock);
scard->auto_cd_mode = 1;
scard->auto_profi_mode = 1;
@@ -6123,7 +6079,7 @@
/*
* Try to grab the PCI device */
-static int __init pdplus_probe(
+static int __devinit pdplus_probe(
pci_dev_t *pci,
pci_device_id_t const *pci_id)
{
@@ -6140,10 +6096,15 @@
LEAVE (-ENOENT);
}
- card = snd_card_new (index[dev], id[dev], THIS_MODULE, sizeof(pdplus_t));
+ card = snd_card_new (index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
LEAVE (-ENOMEM);
+ card->private_data = snd_magic_kcalloc(pdplus_t, 0, GFP_KERNEL);
+ if (card->private_data == NULL) {
+ snd_card_free(card);
+ LEAVE (-ENOMEM);
+ }
card->private_free = pdplus_sweep;
err = pdplus_init (pci, card);
@@ -6157,8 +6118,7 @@
LEAVE (0);
}
-static void __exit pdplus_unregister_iomem (
- snd_iomem_t *iomem)
+static void pdplus_unregister_iomem(snd_iomem_t *iomem)
{
ENTER;
@@ -6168,7 +6128,7 @@
/*
* Release resources */
-static void __exit pdplus_sweep(snd_card_t *card)
+static void pdplus_sweep(snd_card_t *card)
{
pdplus_t *scard;
u_long flags;
@@ -6188,8 +6148,6 @@
write_unlock_irqrestore (&scard->lock, flags);
- pdplus_unregister_proc (scard);
-
pdplus_unregister_iomem (&scard->PLX_iomem);
pdplus_unregister_iomem (&scard->MEM_iomem);
pdplus_unregister_iomem (&scard->FPGA_iomem);
@@ -6200,16 +6158,16 @@
if (scard->irq >= 0)
free_irq(scard->irq, (void *)scard);
+ snd_magic_kfree(scard);
LEAVE_VOID;
}
/*
* Release the PCI device */
-static void __exit pdplus_remove(pci_dev_t *pci)
+static void __devexit pdplus_remove(pci_dev_t *pci)
{
snd_card_t *card;
- pdplus_t *scard;
ENTER;
Vprintk ("MMIO 0= 0x%lx\n", pci_resource_start (pci, 0));
@@ -6217,17 +6175,8 @@
if (card == 0)
Vprintk ("Error: card == %p.\n", card);
- else {
- scard = (pdplus_t *)card->private_data;
- if (scard == NULL)
- Vprintk ("Error: scard == %p.\n", scard);
- else
- pdplus_sweep (card);
- }
-
- snd_magic_kfree (card->private_data);
- card->private_data = NULL;
- snd_card_free (card);
+ else
+ snd_card_free (card);
pci_set_drvdata (pci, NULL);
LEAVE_VOID;
@@ -6246,10 +6195,10 @@
/* ********************************************************************** */
static struct pci_driver driver = {
- name: FULL_NAME,
- id_table: pdplus_ids,
- probe: pdplus_probe,
- remove: pdplus_remove,
+ .name = FULL_NAME,
+ .id_table = pdplus_ids,
+ .probe = pdplus_probe,
+ .remove = __devexit_p(pdplus_remove),
};
static int __init alsa_card_pdplus_init(void)
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog