1
0
Fork 0
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:
Thomas Martitz 2011-12-24 17:59:43 +00:00
parent 2ec443df12
commit a1d3ed2534
4 changed files with 48 additions and 134 deletions

View file

@ -78,13 +78,12 @@ const struct sound_settings_info audiohw_settings[] = {
#endif
};
#ifndef SAMSUNG_YPR0
/* Shadow registers */
static uint8_t as3514_regs[AS3514_NUM_AUDIO_REGS]; /* 8-bit registers */
/*
* 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.
*/
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));
}
#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 */
int tenthdb2master(int db)
{
@ -168,11 +145,8 @@ int sound_val2phys(int setting, int value)
*/
void audiohw_preinit(void)
{
#ifndef SAMSUNG_YPR0
/* read all reg values */
ascodec_readbytes(0x0, AS3514_NUM_AUDIO_REGS, as3514_regs);
#endif
#ifdef HAVE_AS3543

View file

@ -50,6 +50,7 @@
#include "pcm-internal.h"
#include "pcm_mixer.h"
#include "pcm_sampr.h"
#include "audiohw.h"
#include <pthread.h>
#include <signal.h>
@ -320,7 +321,7 @@ void cleanup(void)
void pcm_play_dma_init(void)
{
int err;
audiohw_preinit();
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);
}
pcm_dma_apply_settings();
#ifdef USE_ASYNC_CALLBACK
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@ -352,7 +355,6 @@ void pcm_play_dma_init(void)
tick_add_task(pcm_tick);
#endif
atexit(cleanup);
return;
}
@ -469,6 +471,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
void pcm_play_dma_postinit(void)
{
audiohw_postinit();
}

View file

@ -29,24 +29,12 @@
#include "adc.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);
void ascodec_close(void);
int ascodec_write(unsigned int reg, unsigned int value);
int ascodec_read(unsigned int reg);
void ascodec_write_pmu(unsigned int index, unsigned int subreg, unsigned int value);
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);
unsigned short adc_read(int channel);
void ascodec_lock(void);

View file

@ -32,33 +32,36 @@
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 */
#define IOCTL_REG_WRITE 0x40034101
#define IOCTL_REG_WRITE 0x40034101
/* Write to a PMU register */
#define IOCTL_SUBREG_WRITE 0x40034103
#define IOCTL_SUBREG_WRITE 0x40034103
/* Read from a normal register */
#define IOCTL_REG_READ 0x80034102
#define IOCTL_REG_READ 0x80034102
/* 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);
mutex_init(&as_mtx);
return afe_dev;
}
void ascodec_close(void) {
void ascodec_close(void)
{
if (afe_dev >= 0) {
close(afe_dev);
}
}
/* 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)
{
struct codec_req_struct y;
struct codec_req_struct *p;
p = &y;
p->reg = reg;
p->value = value;
return ioctl(afe_dev, IOCTL_REG_WRITE, p);
struct codec_req_struct r = { .reg = reg, .value = value };
return ioctl(afe_dev, IOCTL_REG_WRITE, &r);
}
int ascodec_read(unsigned int reg)
{
int retval = -1;
struct codec_req_struct y;
struct codec_req_struct *p;
p = &y;
p->reg = reg;
retval = ioctl(afe_dev, IOCTL_REG_READ, p);
struct codec_req_struct r = { .reg = reg };
int retval = ioctl(afe_dev, IOCTL_REG_READ, &r);
if (retval >= 0)
return p->value;
return r.value;
else
return retval;
}
@ -91,114 +86,68 @@ int ascodec_read(unsigned int reg)
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
unsigned int value)
{
struct codec_req_struct y;
struct codec_req_struct *p;
p = &y;
p->reg = index;
p->subreg = subreg;
p->value = value;
ioctl(afe_dev, IOCTL_SUBREG_WRITE, p);
struct codec_req_struct r = {.reg = index, .subreg = subreg, .value = value};
ioctl(afe_dev, IOCTL_SUBREG_WRITE, &r);
}
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
{
int retval = -1;
struct codec_req_struct y;
struct codec_req_struct *p;
p = &y;
p->reg = index;
p->subreg = subreg;
retval = ioctl(afe_dev, IOCTL_SUBREG_READ, p);
struct codec_req_struct r = { .reg = index, .subreg = subreg, };
int retval = ioctl(afe_dev, IOCTL_SUBREG_READ, &r);
if (retval >= 0)
return p->value;
return r.value;
else
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)
{
unsigned int i;
int i, val, ret = 0;
for (i=index; i<len; i++) {
data[i] = ascodec_read(i);
printf("Register %i: value=%i\n",index,data[i]);
for (i = index; i < (int)len; i++) {
val = ascodec_read(i);
if (val >= 0) data[i] = val;
else ret = -1;
}
printf("TOTAL: %i\n", i);
return i;
return ret ?: i; /* i means success */
}
/*
* NOTE:
* 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
* 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
* by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically safe
* Additionally, concurrent ascodec_?(read|write) calls are instead protected
* by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically
* safe
*/
void ascodec_lock(void)
{
mutex_lock(&as_mtx);
}
void ascodec_unlock(void)
{
mutex_unlock(&as_mtx);
}
/* Read 10-bit channel data */
unsigned short adc_read(int channel)
{
unsigned short data = 0;
if ((unsigned)channel >= NUM_ADC_CHANNELS)
return 0;
ascodec_lock();
/* Select channel */
ascodec_write(AS3514_ADC_0, (channel << 4));
unsigned char buf[2];
/*
* The AS3514 ADC will trigger an interrupt when the conversion
* 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 */
ascodec_readbytes(AS3514_ADC_0, sizeof(buf), buf);
/* Read data */
ascodec_readbytes(AS3514_ADC_0, 2, buf);
data = (((buf[0] & 0x3) << 8) | buf[1]);
ascodec_unlock();
return data;
/* decode to 10-bit and return */
return (((buf[0] & 0x3) << 8) | buf[1]);
}
void adc_init(void)