forked from len0rd/rockbox
ypr0: Cleanup and simplify ascodec functions. Fix audiohw_{pre,post}init() not being called.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31423 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2ec443df12
commit
a1d3ed2534
4 changed files with 48 additions and 134 deletions
|
|
@ -78,13 +78,12 @@ const struct sound_settings_info audiohw_settings[] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef SAMSUNG_YPR0
|
|
||||||
/* Shadow registers */
|
/* Shadow registers */
|
||||||
static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */
|
static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* little helper method to set register values.
|
* little helper method to set register values.
|
||||||
* With the help of as3514_regs, we minimize i2c
|
* With the help of as3514_regs, we minimize i2c/syscall
|
||||||
* traffic.
|
* traffic.
|
||||||
*/
|
*/
|
||||||
static void as3514_write(unsigned int reg, unsigned int value)
|
static void as3514_write(unsigned int reg, unsigned int value)
|
||||||
|
|
@ -111,29 +110,7 @@ static void as3514_write_masked(unsigned int reg, unsigned int bits,
|
||||||
{
|
{
|
||||||
as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask));
|
as3514_write(reg, (as3514_regs[reg] & ~mask) | (bits & mask));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void as3514_write(unsigned int reg, unsigned int value)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helpers to set/clear bits */
|
|
||||||
static void as3514_set(unsigned int reg, unsigned int bits)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, ascodec_read(reg) | bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void as3514_clear(unsigned int reg, unsigned int bits)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, ascodec_read(reg) & ~bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void as3514_write_masked(unsigned int reg, unsigned int bits,
|
|
||||||
unsigned int mask)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* convert tenth of dB volume to master volume register value */
|
/* convert tenth of dB volume to master volume register value */
|
||||||
int tenthdb2master(int db)
|
int tenthdb2master(int db)
|
||||||
{
|
{
|
||||||
|
|
@ -168,11 +145,8 @@ int sound_val2phys(int setting, int value)
|
||||||
*/
|
*/
|
||||||
void audiohw_preinit(void)
|
void audiohw_preinit(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef SAMSUNG_YPR0
|
|
||||||
/* read all reg values */
|
/* read all reg values */
|
||||||
ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs);
|
ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_AS3543
|
#ifdef HAVE_AS3543
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "pcm-internal.h"
|
#include "pcm-internal.h"
|
||||||
#include "pcm_mixer.h"
|
#include "pcm_mixer.h"
|
||||||
#include "pcm_sampr.h"
|
#include "pcm_sampr.h"
|
||||||
|
#include "audiohw.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
@ -320,7 +321,7 @@ void cleanup(void)
|
||||||
void pcm_play_dma_init(void)
|
void pcm_play_dma_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
audiohw_preinit();
|
||||||
|
|
||||||
if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
|
if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -343,6 +344,8 @@ void pcm_play_dma_init(void)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcm_dma_apply_settings();
|
||||||
|
|
||||||
#ifdef USE_ASYNC_CALLBACK
|
#ifdef USE_ASYNC_CALLBACK
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
|
|
@ -352,7 +355,6 @@ void pcm_play_dma_init(void)
|
||||||
tick_add_task(pcm_tick);
|
tick_add_task(pcm_tick);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -469,6 +471,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
|
||||||
|
|
||||||
void pcm_play_dma_postinit(void)
|
void pcm_play_dma_postinit(void)
|
||||||
{
|
{
|
||||||
|
audiohw_postinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,24 +29,12 @@
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "ascodec.h"
|
#include "ascodec.h"
|
||||||
|
|
||||||
/* ioctl parameter struct */
|
|
||||||
|
|
||||||
struct codec_req_struct {
|
|
||||||
/* This works for every kind of afe.ko module requests */
|
|
||||||
unsigned char reg; /* Main register address */
|
|
||||||
unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/
|
|
||||||
unsigned char value; /* To be read if reading a register; to be set if writing to a register */
|
|
||||||
};
|
|
||||||
|
|
||||||
int ascodec_init(void);
|
int ascodec_init(void);
|
||||||
void ascodec_close(void);
|
void ascodec_close(void);
|
||||||
int ascodec_write(unsigned int reg, unsigned int value);
|
int ascodec_write(unsigned int reg, unsigned int value);
|
||||||
int ascodec_read(unsigned int reg);
|
int ascodec_read(unsigned int reg);
|
||||||
void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value);
|
void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value);
|
||||||
int ascodec_read_pmu(unsigned int index, unsigned int subreg);
|
int ascodec_read_pmu(unsigned int index, unsigned int subreg);
|
||||||
void ascodec_set(unsigned int reg, unsigned int bits);
|
|
||||||
void ascodec_clear(unsigned int reg, unsigned int bits);
|
|
||||||
void ascodec_write_masked(unsigned int reg, unsigned int bits, unsigned int mask);
|
|
||||||
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
|
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
|
||||||
unsigned short adc_read(int channel);
|
unsigned short adc_read(int channel);
|
||||||
void ascodec_lock(void);
|
void ascodec_lock(void);
|
||||||
|
|
|
||||||
|
|
@ -32,33 +32,36 @@
|
||||||
|
|
||||||
int afe_dev = -1;
|
int afe_dev = -1;
|
||||||
|
|
||||||
|
/* ioctl parameter struct */
|
||||||
|
struct codec_req_struct {
|
||||||
|
/* This works for every kind of afe.ko module requests */
|
||||||
|
unsigned char reg; /* Main register address */
|
||||||
|
unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/
|
||||||
|
unsigned char value; /* To be read if reading a register; to be set if writing to a register */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
/* Write to a normal register */
|
/* Write to a normal register */
|
||||||
#define IOCTL_REG_WRITE 0x40034101
|
#define IOCTL_REG_WRITE 0x40034101
|
||||||
/* Write to a PMU register */
|
/* Write to a PMU register */
|
||||||
#define IOCTL_SUBREG_WRITE 0x40034103
|
#define IOCTL_SUBREG_WRITE 0x40034103
|
||||||
/* Read from a normal register */
|
/* Read from a normal register */
|
||||||
#define IOCTL_REG_READ 0x80034102
|
#define IOCTL_REG_READ 0x80034102
|
||||||
/* Read from a PMU register */
|
/* Read from a PMU register */
|
||||||
#define IOCTL_SUBREG_READ 0x80034103
|
#define IOCTL_SUBREG_READ 0x80034103
|
||||||
|
|
||||||
static struct mutex as_mtx;
|
|
||||||
|
|
||||||
int ascodec_init(void) {
|
|
||||||
|
|
||||||
|
int ascodec_init(void)
|
||||||
|
{
|
||||||
afe_dev = open("/dev/afe", O_RDWR);
|
afe_dev = open("/dev/afe", O_RDWR);
|
||||||
|
|
||||||
mutex_init(&as_mtx);
|
|
||||||
|
|
||||||
return afe_dev;
|
return afe_dev;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ascodec_close(void) {
|
void ascodec_close(void)
|
||||||
|
{
|
||||||
if (afe_dev >= 0) {
|
if (afe_dev >= 0) {
|
||||||
close(afe_dev);
|
close(afe_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read functions returns -1 if fail, otherwise the register's value if success */
|
/* Read functions returns -1 if fail, otherwise the register's value if success */
|
||||||
|
|
@ -66,24 +69,16 @@ void ascodec_close(void) {
|
||||||
|
|
||||||
int ascodec_write(unsigned int reg, unsigned int value)
|
int ascodec_write(unsigned int reg, unsigned int value)
|
||||||
{
|
{
|
||||||
struct codec_req_struct y;
|
struct codec_req_struct r = { .reg = reg, .value = value };
|
||||||
struct codec_req_struct *p;
|
return ioctl(afe_dev, IOCTL_REG_WRITE, &r);
|
||||||
p = &y;
|
|
||||||
p->reg = reg;
|
|
||||||
p->value = value;
|
|
||||||
return ioctl(afe_dev, IOCTL_REG_WRITE, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ascodec_read(unsigned int reg)
|
int ascodec_read(unsigned int reg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
struct codec_req_struct r = { .reg = reg };
|
||||||
struct codec_req_struct y;
|
int retval = ioctl(afe_dev, IOCTL_REG_READ, &r);
|
||||||
struct codec_req_struct *p;
|
|
||||||
p = &y;
|
|
||||||
p->reg = reg;
|
|
||||||
retval = ioctl(afe_dev, IOCTL_REG_READ, p);
|
|
||||||
if (retval >= 0)
|
if (retval >= 0)
|
||||||
return p->value;
|
return r.value;
|
||||||
else
|
else
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
@ -91,114 +86,68 @@ int ascodec_read(unsigned int reg)
|
||||||
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
||||||
unsigned int value)
|
unsigned int value)
|
||||||
{
|
{
|
||||||
struct codec_req_struct y;
|
struct codec_req_struct r = {.reg = index, .subreg = subreg, .value = value};
|
||||||
struct codec_req_struct *p;
|
ioctl(afe_dev, IOCTL_SUBREG_WRITE, &r);
|
||||||
p = &y;
|
|
||||||
p->reg = index;
|
|
||||||
p->subreg = subreg;
|
|
||||||
p->value = value;
|
|
||||||
ioctl(afe_dev, IOCTL_SUBREG_WRITE, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
|
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
struct codec_req_struct r = { .reg = index, .subreg = subreg, };
|
||||||
struct codec_req_struct y;
|
int retval = ioctl(afe_dev, IOCTL_SUBREG_READ, &r);
|
||||||
struct codec_req_struct *p;
|
|
||||||
p = &y;
|
|
||||||
p->reg = index;
|
|
||||||
p->subreg = subreg;
|
|
||||||
retval = ioctl(afe_dev, IOCTL_SUBREG_READ, p);
|
|
||||||
if (retval >= 0)
|
if (retval >= 0)
|
||||||
return p->value;
|
return r.value;
|
||||||
else
|
else
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helpers to set/clear bits */
|
|
||||||
void ascodec_set(unsigned int reg, unsigned int bits)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, ascodec_read(reg) | bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ascodec_clear(unsigned int reg, unsigned int bits)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, ascodec_read(reg) & ~bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ascodec_write_masked(unsigned int reg, unsigned int bits,
|
|
||||||
unsigned int mask)
|
|
||||||
{
|
|
||||||
ascodec_write(reg, (ascodec_read(reg) & ~mask) | (bits & mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*FIXME: doesn't work */
|
|
||||||
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
|
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
int i, val, ret = 0;
|
||||||
|
|
||||||
for (i=index; i<len; i++) {
|
for (i = index; i < (int)len; i++) {
|
||||||
data[i] = ascodec_read(i);
|
val = ascodec_read(i);
|
||||||
printf("Register %i: value=%i\n",index,data[i]);
|
if (val >= 0) data[i] = val;
|
||||||
|
else ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("TOTAL: %i\n", i);
|
return ret ?: i; /* i means success */
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* After the conversion to interrupts, ascodec_(lock|unlock) are only used by
|
* After the conversion to interrupts, ascodec_(lock|unlock) are only used by
|
||||||
* adc-as3514.c to protect against other threads corrupting the result by using
|
* adc-as3514.c to protect against other threads corrupting the result by using
|
||||||
* the ADC at the same time.
|
* the ADC at the same time. this adc_read() doesn't yield but blocks, so
|
||||||
|
* lock/unlock is not needed
|
||||||
*
|
*
|
||||||
* Concurrent ascodec_(async_)?(read|write) calls are instead protected
|
* Additionally, concurrent ascodec_?(read|write) calls are instead protected
|
||||||
* by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically safe
|
* by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically
|
||||||
|
* safe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ascodec_lock(void)
|
void ascodec_lock(void)
|
||||||
{
|
{
|
||||||
mutex_lock(&as_mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ascodec_unlock(void)
|
void ascodec_unlock(void)
|
||||||
{
|
{
|
||||||
mutex_unlock(&as_mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read 10-bit channel data */
|
/* Read 10-bit channel data */
|
||||||
unsigned short adc_read(int channel)
|
unsigned short adc_read(int channel)
|
||||||
{
|
{
|
||||||
unsigned short data = 0;
|
|
||||||
|
|
||||||
if ((unsigned)channel >= NUM_ADC_CHANNELS)
|
if ((unsigned)channel >= NUM_ADC_CHANNELS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ascodec_lock();
|
|
||||||
|
|
||||||
/* Select channel */
|
/* Select channel */
|
||||||
ascodec_write(AS3514_ADC_0, (channel << 4));
|
ascodec_write(AS3514_ADC_0, (channel << 4));
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
|
|
||||||
/*
|
/* Read data */
|
||||||
* The AS3514 ADC will trigger an interrupt when the conversion
|
ascodec_readbytes(AS3514_ADC_0, sizeof(buf), buf);
|
||||||
* is finished, if the corresponding enable bit in IRQ_ENRD2
|
|
||||||
* is set.
|
|
||||||
* Previously the code did not wait and this apparently did
|
|
||||||
* not pose any problems, but this should be more correct.
|
|
||||||
* Without the wait the data read back may be completely or
|
|
||||||
* partially (first one of the two bytes) stale.
|
|
||||||
*/
|
|
||||||
/*FIXME: not implemented*/
|
|
||||||
ascodec_wait_adc_finished();
|
|
||||||
|
|
||||||
/* Read data */
|
/* decode to 10-bit and return */
|
||||||
ascodec_readbytes(AS3514_ADC_0, 2, buf);
|
return (((buf[0] & 0x3) << 8) | buf[1]);
|
||||||
data = (((buf[0] & 0x3) << 8) | buf[1]);
|
|
||||||
|
|
||||||
ascodec_unlock();
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_init(void)
|
void adc_init(void)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue