Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 199f7978 authored by Krzysztof Helt's avatar Krzysztof Helt Committed by Takashi Iwai
Browse files

ALSA: wss-lib: move AD1845 frequency setting into wss-lib



This is required to allow the sscape driver
to autodetect installed codec.

Also, do not create a timer if detected codec
has no hardware timer (e.g. AD1848).

Signed-off-by: default avatarKrzysztof Helt <krzysztof.h1@wp.pl>
Cc: Rene Herman
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c5976504
Loading
Loading
Loading
Loading
+8 −105
Original line number Diff line number Diff line
@@ -129,9 +129,6 @@ enum GA_REG {
#define DMA_8BIT  0x80


#define AD1845_FREQ_SEL_MSB    0x16
#define AD1845_FREQ_SEL_LSB    0x17

enum card_type {
	SSCAPE,
	SSCAPE_PNP,
@@ -954,82 +951,6 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned l
}


/*
 * Override for the CS4231 playback format function.
 * The AD1845 has much simpler format and rate selection.
 */
static void ad1845_playback_format(struct snd_wss *chip,
				   struct snd_pcm_hw_params *params,
				   unsigned char format)
{
	unsigned long flags;
	unsigned rate = params_rate(params);

	/*
	 * The AD1845 can't handle sample frequencies
	 * outside of 4 kHZ to 50 kHZ
	 */
	if (rate > 50000)
		rate = 50000;
	else if (rate < 4000)
		rate = 4000;

	spin_lock_irqsave(&chip->reg_lock, flags);

	/*
	 * Program the AD1845 correctly for the playback stream.
	 * Note that we do NOT need to toggle the MCE bit because
	 * the PLAYBACK_ENABLE bit of the Interface Configuration
	 * register is set.
	 * 
	 * NOTE: We seem to need to write to the MSB before the LSB
	 *       to get the correct sample frequency.
	 */
	snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (format & 0xf0));
	snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
	snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);

	spin_unlock_irqrestore(&chip->reg_lock, flags);
}

/*
 * Override for the CS4231 capture format function. 
 * The AD1845 has much simpler format and rate selection.
 */
static void ad1845_capture_format(struct snd_wss *chip,
				  struct snd_pcm_hw_params *params,
				  unsigned char format)
{
	unsigned long flags;
	unsigned rate = params_rate(params);

	/*
	 * The AD1845 can't handle sample frequencies 
	 * outside of 4 kHZ to 50 kHZ
	 */
	if (rate > 50000)
		rate = 50000;
	else if (rate < 4000)
		rate = 4000;

	spin_lock_irqsave(&chip->reg_lock, flags);

	/*
	 * Program the AD1845 correctly for the playback stream.
	 * Note that we do NOT need to toggle the MCE bit because
	 * the CAPTURE_ENABLE bit of the Interface Configuration
	 * register is set.
	 *
	 * NOTE: We seem to need to write to the MSB before the LSB
	 *       to get the correct sample frequency.
	 */
	snd_wss_out(chip, CS4231_REC_FORMAT, (format & 0xf0));
	snd_wss_out(chip, AD1845_FREQ_SEL_MSB, (unsigned char) (rate >> 8));
	snd_wss_out(chip, AD1845_FREQ_SEL_LSB, (unsigned char) rate);

	spin_unlock_irqrestore(&chip->reg_lock, flags);
}

/*
 * Create an AD1845 PCM subdevice on the SoundScape. The AD1845
 * is very much like a CS4231, with a few extra bits. We will
@@ -1055,11 +976,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
		unsigned long flags;
		struct snd_pcm *pcm;

#define AD1845_FREQ_SEL_ENABLE  0x08

#define AD1845_PWR_DOWN_CTRL   0x1b
#define AD1845_CRYS_CLOCK_SEL  0x1d

/*
 * It turns out that the PLAYBACK_ENABLE bit is set
 * by the lowlevel driver ...
@@ -1074,7 +990,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
 */

		if (sscape->type != SSCAPE_VIVO) {
			int val;
			/*
			 * The input clock frequency on the SoundScape must
			 * be 14.31818 MHz, because we must set this register
@@ -1082,22 +997,10 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
			 */
			snd_wss_mce_up(chip);
			spin_lock_irqsave(&chip->reg_lock, flags);
			snd_wss_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
			snd_wss_out(chip, AD1845_CLOCK, 0x20);
			spin_unlock_irqrestore(&chip->reg_lock, flags);
			snd_wss_mce_down(chip);

			/*
			 * More custom configuration:
			 * a) select "mode 2" and provide a current drive of 8mA
			 * b) enable frequency selection (for capture/playback)
			 */
			spin_lock_irqsave(&chip->reg_lock, flags);
			snd_wss_out(chip, CS4231_MISC_INFO,
				    CS4231_MODE2 | 0x10);
			val = snd_wss_in(chip, AD1845_PWR_DOWN_CTRL);
			snd_wss_out(chip, AD1845_PWR_DOWN_CTRL,
				    val | AD1845_FREQ_SEL_ENABLE);
			spin_unlock_irqrestore(&chip->reg_lock, flags);
		}

		err = snd_wss_pcm(chip, 0, &pcm);
@@ -1113,12 +1016,14 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
					    "for AD1845 chip\n");
			goto _error;
		}
		if (chip->hardware != WSS_HW_AD1848) {
			err = snd_wss_timer(chip, 0, NULL);
			if (err < 0) {
				snd_printk(KERN_ERR "sscape: No timer device "
						    "for AD1845 chip\n");
				goto _error;
			}
		}

		if (sscape->type != SSCAPE_VIVO) {
			err = snd_ctl_add(card,
@@ -1128,8 +1033,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port,
						    "MIDI mixer control\n");
				goto _error;
			}
			chip->set_playback_format = ad1845_playback_format;
			chip->set_capture_format = ad1845_capture_format;
		}

		strcpy(card->driver, "SoundScape");
+40 −0
Original line number Diff line number Diff line
@@ -646,6 +646,24 @@ static void snd_wss_playback_format(struct snd_wss *chip,
			full_calib = 0;
		}
		spin_unlock_irqrestore(&chip->reg_lock, flags);
	} else if (chip->hardware == WSS_HW_AD1845) {
		unsigned rate = params_rate(params);

		/*
		 * Program the AD1845 correctly for the playback stream.
		 * Note that we do NOT need to toggle the MCE bit because
		 * the PLAYBACK_ENABLE bit of the Interface Configuration
		 * register is set.
		 *
		 * NOTE: We seem to need to write to the MSB before the LSB
		 *       to get the correct sample frequency.
		 */
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0));
		snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
		snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
		full_calib = 0;
		spin_unlock_irqrestore(&chip->reg_lock, flags);
	}
	if (full_calib) {
		snd_wss_mce_up(chip);
@@ -690,6 +708,24 @@ static void snd_wss_capture_format(struct snd_wss *chip,
			full_calib = 0;
		}
		spin_unlock_irqrestore(&chip->reg_lock, flags);
	} else if (chip->hardware == WSS_HW_AD1845) {
		unsigned rate = params_rate(params);

		/*
		 * Program the AD1845 correctly for the capture stream.
		 * Note that we do NOT need to toggle the MCE bit because
		 * the PLAYBACK_ENABLE bit of the Interface Configuration
		 * register is set.
		 *
		 * NOTE: We seem to need to write to the MSB before the LSB
		 *       to get the correct sample frequency.
		 */
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0));
		snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
		snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
		full_calib = 0;
		spin_unlock_irqrestore(&chip->reg_lock, flags);
	}
	if (full_calib) {
		snd_wss_mce_up(chip);
@@ -1314,6 +1350,10 @@ static int snd_wss_probe(struct snd_wss *chip)
		chip->image[CS4231_ALT_FEATURE_2] =
			chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
	}
	/* enable fine grained frequency selection */
	if (chip->hardware == WSS_HW_AD1845)
		chip->image[AD1845_PWR_DOWN] = 8;

	ptr = (unsigned char *) &chip->image;
	regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
	snd_wss_mce_down(chip);