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

Commit 6f8acad6 authored by Robert Jarzmik's avatar Robert Jarzmik Committed by Mark Brown
Browse files

ASoC: arm: make pxa2xx-ac97-lib ac97 codec agnostic



All pxa library functions don't use the input parameters for nothing but
slot number. This simplifies their prototypes, and makes them usable by
both the legacy ac97 bus and the new ac97 bus.

Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8d433441
Loading
Loading
Loading
Loading
+9 −6
Original line number Original line Diff line number Diff line
#ifndef PXA2XX_LIB_H
#ifndef PXA2XX_LIB_H
#define PXA2XX_LIB_H
#define PXA2XX_LIB_H


#include <uapi/sound/asound.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <sound/ac97_codec.h>


/* PCM */
/* PCM */
struct snd_pcm_substream;
struct snd_pcm_hw_params;
struct snd_pcm;


extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
extern int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params);
				struct snd_pcm_hw_params *params);
@@ -21,12 +24,12 @@ extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);


/* AC97 */
/* AC97 */


extern unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
extern int pxa2xx_ac97_read(int slot, unsigned short reg);
extern void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
extern int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val);


extern bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97);
extern bool pxa2xx_ac97_try_warm_reset(void);
extern bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97);
extern bool pxa2xx_ac97_try_cold_reset(void);
extern void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97);
extern void pxa2xx_ac97_finish_reset(void);


extern int pxa2xx_ac97_hw_suspend(void);
extern int pxa2xx_ac97_hw_suspend(void);
extern int pxa2xx_ac97_hw_resume(void);
extern int pxa2xx_ac97_hw_resume(void);
+21 −16
Original line number Original line Diff line number Diff line
@@ -20,7 +20,6 @@
#include <linux/io.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio.h>


#include <sound/ac97_codec.h>
#include <sound/pxa2xx-lib.h>
#include <sound/pxa2xx-lib.h>


#include <mach/irqs.h>
#include <mach/irqs.h>
@@ -46,38 +45,41 @@ extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio);
 * 1 jiffy timeout if interrupt never comes).
 * 1 jiffy timeout if interrupt never comes).
 */
 */


unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
int pxa2xx_ac97_read(int slot, unsigned short reg)
{
{
	unsigned short val = -1;
	int val = -ENODEV;
	volatile u32 *reg_addr;
	volatile u32 *reg_addr;


	if (slot > 0)
		return -ENODEV;

	mutex_lock(&car_mutex);
	mutex_lock(&car_mutex);


	/* set up primary or secondary codec space */
	/* set up primary or secondary codec space */
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
		reg_addr = slot ? &SMC_REG_BASE : &PMC_REG_BASE;
	else
	else
		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
		reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
	reg_addr += (reg >> 1);
	reg_addr += (reg >> 1);


	/* start read access across the ac97 link */
	/* start read access across the ac97 link */
	GSR = GSR_CDONE | GSR_SDONE;
	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	gsr_bits = 0;
	val = *reg_addr;
	val = (*reg_addr & 0xffff);
	if (reg == AC97_GPIO_STATUS)
	if (reg == AC97_GPIO_STATUS)
		goto out;
		goto out;
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
	    !((GSR | gsr_bits) & GSR_SDONE)) {
	    !((GSR | gsr_bits) & GSR_SDONE)) {
		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
				__func__, reg, GSR | gsr_bits);
				__func__, reg, GSR | gsr_bits);
		val = -1;
		val = -ETIMEDOUT;
		goto out;
		goto out;
	}
	}


	/* valid data now */
	/* valid data now */
	GSR = GSR_CDONE | GSR_SDONE;
	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	gsr_bits = 0;
	val = *reg_addr;
	val = (*reg_addr & 0xffff);
	/* but we've just started another cycle... */
	/* but we've just started another cycle... */
	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);


@@ -86,29 +88,32 @@ out: mutex_unlock(&car_mutex);
}
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);
EXPORT_SYMBOL_GPL(pxa2xx_ac97_read);


void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
			unsigned short val)
{
{
	volatile u32 *reg_addr;
	volatile u32 *reg_addr;
	int ret = 0;


	mutex_lock(&car_mutex);
	mutex_lock(&car_mutex);


	/* set up primary or secondary codec space */
	/* set up primary or secondary codec space */
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
	if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
		reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
		reg_addr = slot ? &SMC_REG_BASE : &PMC_REG_BASE;
	else
	else
		reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
		reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
	reg_addr += (reg >> 1);
	reg_addr += (reg >> 1);


	GSR = GSR_CDONE | GSR_SDONE;
	GSR = GSR_CDONE | GSR_SDONE;
	gsr_bits = 0;
	gsr_bits = 0;
	*reg_addr = val;
	*reg_addr = val;
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
	    !((GSR | gsr_bits) & GSR_CDONE))
	    !((GSR | gsr_bits) & GSR_CDONE)) {
		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
				__func__, reg, GSR | gsr_bits);
				__func__, reg, GSR | gsr_bits);
		ret = -EIO;
	}


	mutex_unlock(&car_mutex);
	mutex_unlock(&car_mutex);
	return ret;
}
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);


@@ -188,7 +193,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
}
}
#endif
#endif


bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
bool pxa2xx_ac97_try_warm_reset(void)
{
{
	unsigned long gsr;
	unsigned long gsr;
	unsigned int timeout = 100;
	unsigned int timeout = 100;
@@ -225,7 +230,7 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
}
}
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);


bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
bool pxa2xx_ac97_try_cold_reset(void)
{
{
	unsigned long gsr;
	unsigned long gsr;
	unsigned int timeout = 1000;
	unsigned int timeout = 1000;
@@ -263,7 +268,7 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);
EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_cold_reset);




void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
void pxa2xx_ac97_finish_reset(void)
{
{
	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
+27 −8
Original line number Original line Diff line number Diff line
@@ -29,19 +29,38 @@


#include "pxa2xx-pcm.h"
#include "pxa2xx-pcm.h"


static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
static void pxa2xx_ac97_legacy_reset(struct snd_ac97 *ac97)
{
{
	if (!pxa2xx_ac97_try_cold_reset(ac97)) {
	if (!pxa2xx_ac97_try_cold_reset())
		pxa2xx_ac97_try_warm_reset(ac97);
		pxa2xx_ac97_try_warm_reset();

	pxa2xx_ac97_finish_reset();
}
}


	pxa2xx_ac97_finish_reset(ac97);
static unsigned short pxa2xx_ac97_legacy_read(struct snd_ac97 *ac97,
					      unsigned short reg)
{
	int ret;

	ret = pxa2xx_ac97_read(ac97->num, reg);
	if (ret < 0)
		return 0;
	else
		return (unsigned short)(ret & 0xffff);
}

static void pxa2xx_ac97_legacy_write(struct snd_ac97 *ac97,
				     unsigned short reg, unsigned short val)
{
	int __always_unused ret;

	ret = pxa2xx_ac97_write(ac97->num, reg, val);
}
}


static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
	.read	= pxa2xx_ac97_read,
	.read	= pxa2xx_ac97_legacy_read,
	.write	= pxa2xx_ac97_write,
	.write	= pxa2xx_ac97_legacy_write,
	.reset	= pxa2xx_ac97_reset,
	.reset	= pxa2xx_ac97_legacy_reset,
};
};


static struct pxad_param pxa2xx_ac97_pcm_out_req = {
static struct pxad_param pxa2xx_ac97_pcm_out_req = {
+26 −6
Original line number Original line Diff line number Diff line
@@ -29,21 +29,41 @@


static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
static void pxa2xx_ac97_warm_reset(struct snd_ac97 *ac97)
{
{
	pxa2xx_ac97_try_warm_reset(ac97);
	pxa2xx_ac97_try_warm_reset();


	pxa2xx_ac97_finish_reset(ac97);
	pxa2xx_ac97_finish_reset();
}
}


static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
{
{
	pxa2xx_ac97_try_cold_reset(ac97);
	pxa2xx_ac97_try_cold_reset();


	pxa2xx_ac97_finish_reset(ac97);
	pxa2xx_ac97_finish_reset();
}

static unsigned short pxa2xx_ac97_legacy_read(struct snd_ac97 *ac97,
					      unsigned short reg)
{
	int ret;

	ret = pxa2xx_ac97_read(ac97->num, reg);
	if (ret < 0)
		return 0;
	else
		return (unsigned short)(ret & 0xffff);
}

static void pxa2xx_ac97_legacy_write(struct snd_ac97 *ac97,
				     unsigned short reg, unsigned short val)
{
	int ret;

	ret = pxa2xx_ac97_write(ac97->num, reg, val);
}
}


static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
	.read	= pxa2xx_ac97_read,
	.read	= pxa2xx_ac97_legacy_read,
	.write	= pxa2xx_ac97_write,
	.write	= pxa2xx_ac97_legacy_write,
	.warm_reset	= pxa2xx_ac97_warm_reset,
	.warm_reset	= pxa2xx_ac97_warm_reset,
	.reset	= pxa2xx_ac97_cold_reset,
	.reset	= pxa2xx_ac97_cold_reset,
};
};