18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __SOUND_CS5535AUDIO_H
38c2ecf20Sopenharmony_ci#define __SOUND_CS5535AUDIO_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#define cs_writel(cs5535au, reg, val)	outl(val, (cs5535au)->port + reg)
68c2ecf20Sopenharmony_ci#define cs_writeb(cs5535au, reg, val)	outb(val, (cs5535au)->port + reg)
78c2ecf20Sopenharmony_ci#define cs_readl(cs5535au, reg)		inl((cs5535au)->port + reg)
88c2ecf20Sopenharmony_ci#define cs_readw(cs5535au, reg)		inw((cs5535au)->port + reg)
98c2ecf20Sopenharmony_ci#define cs_readb(cs5535au, reg)		inb((cs5535au)->port + reg)
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define CS5535AUDIO_MAX_DESCRIPTORS	128
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/* acc_codec bar0 reg addrs */
148c2ecf20Sopenharmony_ci#define ACC_GPIO_STATUS			0x00
158c2ecf20Sopenharmony_ci#define ACC_CODEC_STATUS		0x08
168c2ecf20Sopenharmony_ci#define ACC_CODEC_CNTL			0x0C
178c2ecf20Sopenharmony_ci#define ACC_IRQ_STATUS			0x12
188c2ecf20Sopenharmony_ci#define ACC_BM0_CMD			0x20
198c2ecf20Sopenharmony_ci#define ACC_BM1_CMD			0x28
208c2ecf20Sopenharmony_ci#define ACC_BM0_PRD			0x24
218c2ecf20Sopenharmony_ci#define ACC_BM1_PRD			0x2C
228c2ecf20Sopenharmony_ci#define ACC_BM0_STATUS			0x21
238c2ecf20Sopenharmony_ci#define ACC_BM1_STATUS			0x29
248c2ecf20Sopenharmony_ci#define ACC_BM0_PNTR			0x60
258c2ecf20Sopenharmony_ci#define ACC_BM1_PNTR			0x64
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/* acc_codec bar0 reg bits */
288c2ecf20Sopenharmony_ci/* ACC_IRQ_STATUS */
298c2ecf20Sopenharmony_ci#define IRQ_STS 			0
308c2ecf20Sopenharmony_ci#define WU_IRQ_STS 			1
318c2ecf20Sopenharmony_ci#define BM0_IRQ_STS 			2
328c2ecf20Sopenharmony_ci#define BM1_IRQ_STS 			3
338c2ecf20Sopenharmony_ci/* ACC_BMX_STATUS */
348c2ecf20Sopenharmony_ci#define EOP				(1<<0)
358c2ecf20Sopenharmony_ci#define BM_EOP_ERR			(1<<1)
368c2ecf20Sopenharmony_ci/* ACC_BMX_CTL */
378c2ecf20Sopenharmony_ci#define BM_CTL_EN			0x01
388c2ecf20Sopenharmony_ci#define BM_CTL_PAUSE			0x03
398c2ecf20Sopenharmony_ci#define BM_CTL_DIS			0x00
408c2ecf20Sopenharmony_ci#define BM_CTL_BYTE_ORD_LE		0x00
418c2ecf20Sopenharmony_ci#define BM_CTL_BYTE_ORD_BE		0x04
428c2ecf20Sopenharmony_ci/* cs5535 specific ac97 codec register defines */
438c2ecf20Sopenharmony_ci#define CMD_MASK			0xFF00FFFF
448c2ecf20Sopenharmony_ci#define CMD_NEW				0x00010000
458c2ecf20Sopenharmony_ci#define STS_NEW				0x00020000
468c2ecf20Sopenharmony_ci#define PRM_RDY_STS			0x00800000
478c2ecf20Sopenharmony_ci#define ACC_CODEC_CNTL_WR_CMD		(~0x80000000)
488c2ecf20Sopenharmony_ci#define ACC_CODEC_CNTL_RD_CMD		0x80000000
498c2ecf20Sopenharmony_ci#define ACC_CODEC_CNTL_LNK_SHUTDOWN	0x00040000
508c2ecf20Sopenharmony_ci#define ACC_CODEC_CNTL_LNK_WRM_RST	0x00020000
518c2ecf20Sopenharmony_ci#define PRD_JMP				0x2000
528c2ecf20Sopenharmony_ci#define PRD_EOP				0x4000
538c2ecf20Sopenharmony_ci#define PRD_EOT				0x8000
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cienum { CS5535AUDIO_DMA_PLAYBACK, CS5535AUDIO_DMA_CAPTURE, NUM_CS5535AUDIO_DMAS };
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistruct cs5535audio;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct cs5535audio_dma_ops {
608c2ecf20Sopenharmony_ci	int type;
618c2ecf20Sopenharmony_ci	void (*enable_dma)(struct cs5535audio *cs5535au);
628c2ecf20Sopenharmony_ci	void (*disable_dma)(struct cs5535audio *cs5535au);
638c2ecf20Sopenharmony_ci	void (*pause_dma)(struct cs5535audio *cs5535au);
648c2ecf20Sopenharmony_ci	void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr);
658c2ecf20Sopenharmony_ci	u32 (*read_prd)(struct cs5535audio *cs5535au);
668c2ecf20Sopenharmony_ci	u32 (*read_dma_pntr)(struct cs5535audio *cs5535au);
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct cs5535audio_dma_desc {
708c2ecf20Sopenharmony_ci	__le32 addr;
718c2ecf20Sopenharmony_ci	__le16 size;
728c2ecf20Sopenharmony_ci	__le16 ctlreserved;
738c2ecf20Sopenharmony_ci};
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistruct cs5535audio_dma {
768c2ecf20Sopenharmony_ci	const struct cs5535audio_dma_ops *ops;
778c2ecf20Sopenharmony_ci	struct snd_dma_buffer desc_buf;
788c2ecf20Sopenharmony_ci	struct snd_pcm_substream *substream;
798c2ecf20Sopenharmony_ci	unsigned int buf_addr, buf_bytes;
808c2ecf20Sopenharmony_ci	unsigned int period_bytes, periods;
818c2ecf20Sopenharmony_ci	u32 saved_prd;
828c2ecf20Sopenharmony_ci	int pcm_open_flag;
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistruct cs5535audio {
868c2ecf20Sopenharmony_ci	struct snd_card *card;
878c2ecf20Sopenharmony_ci	struct snd_ac97 *ac97;
888c2ecf20Sopenharmony_ci	struct snd_pcm *pcm;
898c2ecf20Sopenharmony_ci	int irq;
908c2ecf20Sopenharmony_ci	struct pci_dev *pci;
918c2ecf20Sopenharmony_ci	unsigned long port;
928c2ecf20Sopenharmony_ci	spinlock_t reg_lock;
938c2ecf20Sopenharmony_ci	struct snd_pcm_substream *playback_substream;
948c2ecf20Sopenharmony_ci	struct snd_pcm_substream *capture_substream;
958c2ecf20Sopenharmony_ci	struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
968c2ecf20Sopenharmony_ci};
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciextern const struct dev_pm_ops snd_cs5535audio_pm;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci#ifdef CONFIG_OLPC
1018c2ecf20Sopenharmony_civoid olpc_prequirks(struct snd_card *card,
1028c2ecf20Sopenharmony_ci		    struct snd_ac97_template *ac97);
1038c2ecf20Sopenharmony_ciint olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
1048c2ecf20Sopenharmony_civoid olpc_quirks_cleanup(void);
1058c2ecf20Sopenharmony_civoid olpc_analog_input(struct snd_ac97 *ac97, int on);
1068c2ecf20Sopenharmony_civoid olpc_mic_bias(struct snd_ac97 *ac97, int on);
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic inline void olpc_capture_open(struct snd_ac97 *ac97)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	/* default to Analog Input off */
1118c2ecf20Sopenharmony_ci	olpc_analog_input(ac97, 0);
1128c2ecf20Sopenharmony_ci	/* enable MIC Bias for recording */
1138c2ecf20Sopenharmony_ci	olpc_mic_bias(ac97, 1);
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistatic inline void olpc_capture_close(struct snd_ac97 *ac97)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	/* disable Analog Input */
1198c2ecf20Sopenharmony_ci	olpc_analog_input(ac97, 0);
1208c2ecf20Sopenharmony_ci	/* disable the MIC Bias (so the recording LED turns off) */
1218c2ecf20Sopenharmony_ci	olpc_mic_bias(ac97, 0);
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci#else
1248c2ecf20Sopenharmony_cistatic inline void olpc_prequirks(struct snd_card *card,
1258c2ecf20Sopenharmony_ci		struct snd_ac97_template *ac97) { }
1268c2ecf20Sopenharmony_cistatic inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
1278c2ecf20Sopenharmony_ci{
1288c2ecf20Sopenharmony_ci	return 0;
1298c2ecf20Sopenharmony_ci}
1308c2ecf20Sopenharmony_cistatic inline void olpc_quirks_cleanup(void) { }
1318c2ecf20Sopenharmony_cistatic inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
1328c2ecf20Sopenharmony_cistatic inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
1338c2ecf20Sopenharmony_cistatic inline void olpc_capture_open(struct snd_ac97 *ac97) { }
1348c2ecf20Sopenharmony_cistatic inline void olpc_capture_close(struct snd_ac97 *ac97) { }
1358c2ecf20Sopenharmony_ci#endif
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciint snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#endif /* __SOUND_CS5535AUDIO_H */
1408c2ecf20Sopenharmony_ci
141