Merge remote-tracking branches 'asoc/topic/ac97', 'asoc/topic/ac97-mfd', 'asoc/topic/amd' and 'asoc/topic/arizona-mfd' into asoc-next
Cette révision appartient à :
@@ -20,7 +20,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/pxa2xx-lib.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).
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
if (slot > 0)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
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
|
||||
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
reg_addr += (reg >> 1);
|
||||
|
||||
/* start read access across the ac97 link */
|
||||
GSR = GSR_CDONE | GSR_SDONE;
|
||||
gsr_bits = 0;
|
||||
val = *reg_addr;
|
||||
val = (*reg_addr & 0xffff);
|
||||
if (reg == AC97_GPIO_STATUS)
|
||||
goto out;
|
||||
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
|
||||
!((GSR | gsr_bits) & GSR_SDONE)) {
|
||||
printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
|
||||
__func__, reg, GSR | gsr_bits);
|
||||
val = -1;
|
||||
val = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* valid data now */
|
||||
GSR = GSR_CDONE | GSR_SDONE;
|
||||
gsr_bits = 0;
|
||||
val = *reg_addr;
|
||||
val = (*reg_addr & 0xffff);
|
||||
/* but we've just started another cycle... */
|
||||
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);
|
||||
|
||||
void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
|
||||
unsigned short val)
|
||||
int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val)
|
||||
{
|
||||
volatile u32 *reg_addr;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
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
|
||||
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
reg_addr = slot ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
reg_addr += (reg >> 1);
|
||||
|
||||
GSR = GSR_CDONE | GSR_SDONE;
|
||||
gsr_bits = 0;
|
||||
*reg_addr = val;
|
||||
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",
|
||||
__func__, reg, GSR | gsr_bits);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
mutex_unlock(&car_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_write);
|
||||
|
||||
@@ -188,7 +193,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
|
||||
bool pxa2xx_ac97_try_warm_reset(void)
|
||||
{
|
||||
unsigned long gsr;
|
||||
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);
|
||||
|
||||
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
|
||||
bool pxa2xx_ac97_try_cold_reset(void)
|
||||
{
|
||||
unsigned long gsr;
|
||||
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);
|
||||
|
||||
|
||||
void pxa2xx_ac97_finish_reset(struct snd_ac97 *ac97)
|
||||
void pxa2xx_ac97_finish_reset(void)
|
||||
{
|
||||
GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
|
||||
GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
|
||||
|
@@ -29,19 +29,38 @@
|
||||
|
||||
#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)) {
|
||||
pxa2xx_ac97_try_warm_reset(ac97);
|
||||
}
|
||||
if (!pxa2xx_ac97_try_cold_reset())
|
||||
pxa2xx_ac97_try_warm_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 __always_unused ret;
|
||||
|
||||
ret = pxa2xx_ac97_write(ac97->num, reg, val);
|
||||
}
|
||||
|
||||
static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
|
||||
.read = pxa2xx_ac97_read,
|
||||
.write = pxa2xx_ac97_write,
|
||||
.reset = pxa2xx_ac97_reset,
|
||||
.read = pxa2xx_ac97_legacy_read,
|
||||
.write = pxa2xx_ac97_legacy_write,
|
||||
.reset = pxa2xx_ac97_legacy_reset,
|
||||
};
|
||||
|
||||
static struct pxad_param pxa2xx_ac97_pcm_out_req = {
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur