Browse Source

split up olpc patches

SVN-Revision: 10069
John Crispin 18 years ago
parent
commit
6286c19540
2 changed files with 414 additions and 5520 deletions
  1. 0 5520
      target/linux/olpc/patches/100-olpc.patch
  2. 414 0
      target/linux/olpc/patches/110-olpc_sound.patch

File diff suppressed because it is too large
+ 0 - 5520
target/linux/olpc/patches/100-olpc.patch


+ 414 - 0
target/linux/olpc/patches/110-olpc_sound.patch

@@ -0,0 +1,414 @@
+diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
+index 246ac23..874a2c8 100644
+--- a/include/sound/ac97_codec.h
++++ b/include/sound/ac97_codec.h
+@@ -281,10 +281,12 @@
+ /* specific - Analog Devices */
+ #define AC97_AD_TEST		0x5a	/* test register */
+ #define AC97_AD_TEST2		0x5c	/* undocumented test register 2 */
++#define AC97_AD_HPFD_SHIFT	12	/* High Pass Filter Disable */
+ #define AC97_AD_CODEC_CFG	0x70	/* codec configuration */
+ #define AC97_AD_JACK_SPDIF	0x72	/* Jack Sense & S/PDIF */
+ #define AC97_AD_SERIAL_CFG	0x74	/* Serial Configuration */
+ #define AC97_AD_MISC		0x76	/* Misc Control Bits */
++#define AC97_AD_VREFD_SHIFT	2	/* V_REFOUT Disable (AD1888) */
+ 
+ /* specific - Cirrus Logic */
+ #define AC97_CSR_ACMODE		0x5e	/* AC Mode Register */
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
+index bbed644..090e852 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -49,7 +49,7 @@ module_param(enable_loopback, bool, 0444);
+ MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
+ 
+ #ifdef CONFIG_SND_AC97_POWER_SAVE
+-static int power_save;
++static int power_save = 1;
+ module_param(power_save, bool, 0644);
+ MODULE_PARM_DESC(power_save, "Enable AC97 power-saving control");
+ #endif
+diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
+index 581ebba..06637f7 100644
+--- a/sound/pci/ac97/ac97_patch.c
++++ b/sound/pci/ac97/ac97_patch.c
+@@ -1973,8 +1973,9 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
+ 		.get = snd_ac97_ad1888_lohpsel_get,
+ 		.put = snd_ac97_ad1888_lohpsel_put
+ 	},
+-	AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1),
+-	AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
++	AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
++	AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
++			AC97_AD_HPFD_SHIFT, 1, 1),
+ 	AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
+index ad947b4..3866c4d 100644
+--- a/sound/pci/cs5535audio/Makefile
++++ b/sound/pci/cs5535audio/Makefile
+@@ -8,5 +8,9 @@ ifeq ($(CONFIG_PM),y)
+ snd-cs5535audio-objs += cs5535audio_pm.o
+ endif
+ 
++ifdef CONFIG_OLPC
++snd-cs5535audio-objs += cs5535audio_olpc.o
++endif
++
+ # Toplevel Module Dependency
+ obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
+diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
+index b8e75ef..389d9da 100644
+--- a/sound/pci/cs5535audio/cs5535audio.c
++++ b/sound/pci/cs5535audio/cs5535audio.c
+@@ -145,7 +145,7 @@ static unsigned short snd_cs5535audio_ac97_codec_read(struct snd_ac97 *ac97,
+ 	return snd_cs5535audio_codec_read(cs5535au, reg);
+ }
+ 
+-static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
++static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
+ {
+ 	struct snd_card *card = cs5535au->card;
+ 	struct snd_ac97_bus *pbus;
+@@ -160,10 +160,14 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
+ 		return err;
+ 
+ 	memset(&ac97, 0, sizeof(ac97));
+-	ac97.scaps = AC97_SCAP_AUDIO|AC97_SCAP_SKIP_MODEM;
++	ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM
++			| AC97_SCAP_POWER_SAVE;
+ 	ac97.private_data = cs5535au;
+ 	ac97.pci = cs5535au->pci;
+ 
++	/* olpc_prequirks is dummied out if not olpc */
++	olpc_prequirks(card, &ac97);
++
+ 	if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
+ 		snd_printk(KERN_ERR "mixer failed\n");
+ 		return err;
+@@ -171,6 +175,12 @@ static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
+ 
+ 	snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
+ 
++	/* olpc_quirks is dummied out if not olpc */
++	if (( err = olpc_quirks(card, cs5535au->ac97)) < 0) {
++		snd_printk(KERN_ERR "olpc quirks failed\n");
++		return err;
++	}
++
+ 	return 0;
+ }
+ 
+@@ -206,7 +216,6 @@ static void process_bm1_irq(struct cs5535audio *cs5535au)
+ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
+ {
+ 	u16 acc_irq_stat;
+-	u8 bm_stat;
+ 	unsigned char count;
+ 	struct cs5535audio *cs5535au = dev_id;
+ 
+@@ -217,7 +226,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
+ 
+ 	if (!acc_irq_stat)
+ 		return IRQ_NONE;
+-	for (count = 0; count < 10; count++) {
++	for (count = 0; count < 4; count++) {
+ 		if (acc_irq_stat & (1 << count)) {
+ 			switch (count) {
+ 			case IRQ_STS:
+@@ -232,26 +241,9 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
+ 			case BM1_IRQ_STS:
+ 				process_bm1_irq(cs5535au);
+ 				break;
+-			case BM2_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM2_STATUS);
+-				break;
+-			case BM3_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM3_STATUS);
+-				break;
+-			case BM4_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM4_STATUS);
+-				break;
+-			case BM5_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM5_STATUS);
+-				break;
+-			case BM6_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM6_STATUS);
+-				break;
+-			case BM7_IRQ_STS:
+-				bm_stat = cs_readb(cs5535au, ACC_BM7_STATUS);
+-				break;
+ 			default:
+-				snd_printk(KERN_ERR "Unexpected irq src\n");
++				snd_printk(KERN_ERR "Unexpected irq src: "
++						"0x%x\n", acc_irq_stat);
+ 				break;
+ 			}
+ 		}
+diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
+index 4fd1f31..ff82f10 100644
+--- a/sound/pci/cs5535audio/cs5535audio.h
++++ b/sound/pci/cs5535audio/cs5535audio.h
+@@ -16,57 +16,28 @@
+ #define ACC_IRQ_STATUS			0x12
+ #define ACC_BM0_CMD			0x20
+ #define ACC_BM1_CMD			0x28
+-#define ACC_BM2_CMD			0x30
+-#define ACC_BM3_CMD			0x38
+-#define ACC_BM4_CMD			0x40
+-#define ACC_BM5_CMD			0x48
+-#define ACC_BM6_CMD			0x50
+-#define ACC_BM7_CMD			0x58
+ #define ACC_BM0_PRD			0x24
+ #define ACC_BM1_PRD			0x2C
+-#define ACC_BM2_PRD			0x34
+-#define ACC_BM3_PRD			0x3C
+-#define ACC_BM4_PRD			0x44
+-#define ACC_BM5_PRD			0x4C
+-#define ACC_BM6_PRD			0x54
+-#define ACC_BM7_PRD			0x5C
+ #define ACC_BM0_STATUS			0x21
+ #define ACC_BM1_STATUS			0x29
+-#define ACC_BM2_STATUS			0x31
+-#define ACC_BM3_STATUS			0x39
+-#define ACC_BM4_STATUS			0x41
+-#define ACC_BM5_STATUS			0x49
+-#define ACC_BM6_STATUS			0x51
+-#define ACC_BM7_STATUS			0x59
+ #define ACC_BM0_PNTR			0x60
+ #define ACC_BM1_PNTR			0x64
+-#define ACC_BM2_PNTR			0x68
+-#define ACC_BM3_PNTR			0x6C
+-#define ACC_BM4_PNTR			0x70
+-#define ACC_BM5_PNTR			0x74
+-#define ACC_BM6_PNTR			0x78
+-#define ACC_BM7_PNTR			0x7C
++
+ /* acc_codec bar0 reg bits */
+ /* ACC_IRQ_STATUS */
+ #define IRQ_STS 			0
+ #define WU_IRQ_STS 			1
+ #define BM0_IRQ_STS 			2
+ #define BM1_IRQ_STS 			3
+-#define BM2_IRQ_STS 			4
+-#define BM3_IRQ_STS 			5
+-#define BM4_IRQ_STS 			6
+-#define BM5_IRQ_STS		 	7
+-#define BM6_IRQ_STS 			8
+-#define BM7_IRQ_STS 			9
+ /* ACC_BMX_STATUS */
+ #define EOP				(1<<0)
+ #define BM_EOP_ERR			(1<<1)
+ /* ACC_BMX_CTL */
+-#define BM_CTL_EN			0x00000001
+-#define BM_CTL_PAUSE			0x00000011
+-#define BM_CTL_DIS			0x00000000
+-#define BM_CTL_BYTE_ORD_LE		0x00000000
+-#define BM_CTL_BYTE_ORD_BE		0x00000100
++#define BM_CTL_EN			0x01
++#define BM_CTL_PAUSE			0x03
++#define BM_CTL_DIS			0x00
++#define BM_CTL_BYTE_ORD_LE		0x00
++#define BM_CTL_BYTE_ORD_BE		0x04
+ /* cs5535 specific ac97 codec register defines */
+ #define CMD_MASK			0xFF00FFFF
+ #define CMD_NEW				0x00010000
+@@ -106,8 +77,8 @@ struct cs5535audio_dma {
+ 	struct snd_pcm_substream *substream;
+ 	unsigned int buf_addr, buf_bytes;
+ 	unsigned int period_bytes, periods;
+-	int suspended;
+ 	u32 saved_prd;
++	int pcm_open_flag;
+ };
+ 
+ struct cs5535audio {
+@@ -123,8 +94,21 @@ struct cs5535audio {
+ 	struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
+ };
+ 
++#ifdef CONFIG_PM
+ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
+ int snd_cs5535audio_resume(struct pci_dev *pci);
++#endif
++
++#ifdef CONFIG_OLPC
++void olpc_prequirks(struct snd_card *card, struct snd_ac97_template *ac97) __devinit;
++int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97) __devinit;
++int olpc_ai_enable(struct snd_ac97 *ac97, u8 val);
++#else
++#define olpc_prequirks(arg,arg2)	do {} while (0)
++#define olpc_quirks(arg,arg2)		(0)
++#define olpc_ai_enable(a, v) (0)
++#endif
++
+ int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
+ 
+ #endif /* __SOUND_CS5535AUDIO_H */
+diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
+index 5450a9e..d23f8ea 100644
+--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
++++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
+@@ -164,6 +164,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
+ 	jmpprd_addr = cpu_to_le32(lastdesc->addr +
+ 				  (sizeof(struct cs5535audio_dma_desc)*periods));
+ 
++	dma->substream = substream;
+ 	dma->period_bytes = period_bytes;
+ 	dma->periods = periods;
+ 	spin_lock_irq(&cs5535au->reg_lock);
+@@ -241,6 +242,7 @@ static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
+ {
+ 	snd_dma_free_pages(&dma->desc_buf);
+ 	dma->desc_buf.area = NULL;
++	dma->substream = NULL;
+ }
+ 
+ static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
+@@ -260,6 +262,9 @@ static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
+ 	err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
+ 					    params_periods(hw_params),
+ 					    params_period_bytes(hw_params));
++	if (!err)
++		dma->pcm_open_flag = 1;
++
+ 	return err;
+ }
+ 
+@@ -268,6 +273,15 @@ static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
+ 	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+ 	struct cs5535audio_dma *dma = substream->runtime->private_data;
+ 
++	if (dma->pcm_open_flag) {
++		if (substream == cs5535au->playback_substream)
++			snd_ac97_update_power(cs5535au->ac97,
++					AC97_PCM_FRONT_DAC_RATE, 0);
++		else
++			snd_ac97_update_power(cs5535au->ac97,
++					AC97_PCM_LR_ADC_RATE, 0);
++		dma->pcm_open_flag = 0;
++	}
+ 	cs5535audio_clear_dma_packets(cs5535au, dma, substream);
+ 	return snd_pcm_lib_free_pages(substream);
+ }
+@@ -298,14 +312,12 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_RESUME:
+ 		dma->ops->enable_dma(cs5535au);
+-		dma->suspended = 0;
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 		dma->ops->disable_dma(cs5535au);
+ 		break;
+ 	case SNDRV_PCM_TRIGGER_SUSPEND:
+ 		dma->ops->disable_dma(cs5535au);
+-		dma->suspended = 1;
+ 		break;
+ 	default:
+ 		snd_printk(KERN_ERR "unhandled trigger\n");
+@@ -344,6 +356,7 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
+ 	int err;
+ 	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
++	struct snd_ac97 *ac97 = cs5535au->ac97;
+ 
+ 	runtime->hw = snd_cs5535audio_capture;
+ 	cs5535au->capture_substream = substream;
+@@ -352,11 +365,29 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
+ 	if ((err = snd_pcm_hw_constraint_integer(runtime,
+ 					 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+ 		return err;
+-	return 0;
++
++#ifdef CONFIG_OLPC
++	/* Disable Analog Input */
++	olpc_ai_enable(ac97, 0);
++	/* Enable V_ref bias while recording. */
++	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1<<AC97_AD_VREFD_SHIFT, 0);
++#endif
++	return err;
+ }
+ 
+ static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
+ {
++#ifdef CONFIG_OLPC
++	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
++	struct snd_ac97 *ac97 = cs5535au->ac97;
++
++	/* Disable Analog Input */
++	olpc_ai_enable(ac97, 0);
++	/* Disable V_ref bias. */
++	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1<<AC97_AD_VREFD_SHIFT,
++			1<<AC97_AD_VREFD_SHIFT);
++#endif
++
+ 	return 0;
+ }
+ 
+diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
+index 3e4d198..838708f 100644
+--- a/sound/pci/cs5535audio/cs5535audio_pm.c
++++ b/sound/pci/cs5535audio/cs5535audio_pm.c
+@@ -64,18 +64,21 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
+ 	int i;
+ 
+ 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
++	snd_pcm_suspend_all(cs5535au->pcm);
++	snd_ac97_suspend(cs5535au->ac97);
+ 	for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
+ 		struct cs5535audio_dma *dma = &cs5535au->dmas[i];
+-		if (dma && dma->substream && !dma->suspended) 
++		if (dma && dma->substream)
+ 			dma->saved_prd = dma->ops->read_prd(cs5535au);
+ 	}
+-	snd_pcm_suspend_all(cs5535au->pcm);
+-	snd_ac97_suspend(cs5535au->ac97);
+ 	/* save important regs, then disable aclink in hw */
+ 	snd_cs5535audio_stop_hardware(cs5535au);
+ 
++	if (pci_save_state(pci)) {
++		printk(KERN_ERR "cs5535audio: pci_save_state failed!\n");
++		return -EIO;
++	}
+ 	pci_disable_device(pci);
+-	pci_save_state(pci);
+ 	pci_set_power_state(pci, pci_choose_state(pci, state));
+ 	return 0;
+ }
+@@ -89,7 +92,12 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
+ 	int i;
+ 
+ 	pci_set_power_state(pci, PCI_D0);
+-	pci_restore_state(pci);
++	if (pci_restore_state(pci) < 0) {
++		printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
++		       "disabling device\n");
++		snd_card_disconnect(card);
++		return -EIO;
++	}
+ 	if (pci_enable_device(pci) < 0) {
+ 		printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
+ 		       "disabling device\n");
+@@ -112,17 +120,17 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
+ 	if (!timeout)
+ 		snd_printk(KERN_ERR "Failure getting AC Link ready\n");
+ 
+-	/* we depend on ac97 to perform the codec power up */
+-	snd_ac97_resume(cs5535au->ac97);
+ 	/* set up rate regs, dma. actual initiation is done in trig */
+ 	for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
+ 		struct cs5535audio_dma *dma = &cs5535au->dmas[i];
+-		if (dma && dma->substream && dma->suspended) {
++		if (dma && dma->substream) {
+ 			dma->substream->ops->prepare(dma->substream);
+ 			dma->ops->setup_prd(cs5535au, dma->saved_prd);
+ 		}
+ 	}
+-		
++
++	/* we depend on ac97 to perform the codec power up */
++	snd_ac97_resume(cs5535au->ac97);
+ 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ 
+ 	return 0;

Some files were not shown because too many files changed in this diff