From a1d3ed25346ab4174cb7fd066158cebc8e29fc79 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Sat, 24 Dec 2011 17:59:43 +0000 Subject: 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 --- firmware/drivers/audio/as3514.c | 28 +----- firmware/target/hosted/pcm-alsa.c | 7 +- firmware/target/hosted/ypr0/ascodec-target.h | 12 --- firmware/target/hosted/ypr0/ascodec-ypr0.c | 137 +++++++++------------------ 4 files changed, 49 insertions(+), 135 deletions(-) (limited to 'firmware') diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 0fe3070c19..a430afdf88 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c @@ -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 diff --git a/firmware/target/hosted/pcm-alsa.c b/firmware/target/hosted/pcm-alsa.c index 928187993e..7daf485f18 100644 --- a/firmware/target/hosted/pcm-alsa.c +++ b/firmware/target/hosted/pcm-alsa.c @@ -50,6 +50,7 @@ #include "pcm-internal.h" #include "pcm_mixer.h" #include "pcm_sampr.h" +#include "audiohw.h" #include #include @@ -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(); } diff --git a/firmware/target/hosted/ypr0/ascodec-target.h b/firmware/target/hosted/ypr0/ascodec-target.h index f4ecf20a1b..2274d5f073 100644 --- a/firmware/target/hosted/ypr0/ascodec-target.h +++ b/firmware/target/hosted/ypr0/ascodec-target.h @@ -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); diff --git a/firmware/target/hosted/ypr0/ascodec-ypr0.c b/firmware/target/hosted/ypr0/ascodec-ypr0.c index a4e92e6f6b..b3bc48290f 100644 --- a/firmware/target/hosted/ypr0/ascodec-ypr0.c +++ b/firmware/target/hosted/ypr0/ascodec-ypr0.c @@ -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 - -static struct mutex as_mtx; +#define IOCTL_SUBREG_READ 0x80034103 -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= 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, 2, buf); - data = (((buf[0] & 0x3) << 8) | buf[1]); - - ascodec_unlock(); - return data; + /* Read data */ + ascodec_readbytes(AS3514_ADC_0, sizeof(buf), buf); + + /* decode to 10-bit and return */ + return (((buf[0] & 0x3) << 8) | buf[1]); } void adc_init(void) -- cgit v1.2.3