Ingenic targets:

* Clean up codec & PCM + functional changes
 * LCD: Don't wait on DMAC in lcd_unlock()
 * SADC: add battery mutex + other changes
 * NAND: add mutex
 * USB rework (still not working)


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19327 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Maurus Cuelenaere 2008-12-04 18:26:19 +00:00
parent b2dd3c210e
commit a119c44c7e
10 changed files with 361 additions and 1183 deletions

View file

@ -2339,6 +2339,7 @@
#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */
#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */
#define USB_REG_COUNT0 (USB_BASE + 0x18) /* bytes in EP0 FIFO 16-bit */
#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */
#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */
#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */
@ -2375,6 +2376,7 @@
#define REG_USB_REG_TESTMODE REG8(USB_REG_TESTMODE)
#define REG_USB_REG_CSR0 REG8(USB_REG_CSR0)
#define REG_USB_REG_COUNT0 REG16(USB_REG_COUNT0)
#define REG_USB_REG_INMAXP REG16(USB_REG_INMAXP)
#define REG_USB_REG_INCSR REG16(USB_REG_INCSR)
#define REG_USB_REG_INCSRH REG8(USB_REG_INCSRH)
@ -2395,6 +2397,9 @@
#define REG_USB_REG_ADDR2 REG32(USB_REG_ADDR2)
#define REG_USB_REG_COUNT2 REG32(USB_REG_COUNT2)
#define REG_USB_REG_EPINFO REG16(USB_REG_EPINFO)
#define REG_USB_REG_RAMINFO REG8(USB_REG_RAMINFO)
/* Power register bit masks */
#define USB_POWER_SUSPENDM 0x01
@ -2414,6 +2419,8 @@
#define USB_INTR_OUTEP1 0x0002
#define USB_INTR_OUTEP2 0x0004
#define USB_INTR_EP(n) (n*2)
/* CSR0 bit masks */
#define USB_CSR0_OUTPKTRDY 0x01
#define USB_CSR0_INPKTRDY 0x02
@ -2425,11 +2432,11 @@
#define USB_CSR0_SVDSETUPEND 0x80
/* Endpoint CSR register bits */
#define USB_INCSRH_AUTOSET 0x80
#define USB_INCSRH_ISO 0x40
#define USB_INCSRH_MODE 0x20
#define USB_INCSRH_DMAREQENAB 0x10
#define USB_INCSRH_DMAREQMODE 0x04
#define USB_INCSRH_AUTOSET 0x8000
#define USB_INCSRH_ISO 0x4000
#define USB_INCSRH_MODE 0x2000
#define USB_INCSRH_DMAREQENAB 0x1000
#define USB_INCSRH_DMAREQMODE 0x0400
#define USB_INCSR_CDT 0x40
#define USB_INCSR_SENTSTALL 0x20
#define USB_INCSR_SENDSTALL 0x10
@ -2437,11 +2444,11 @@
#define USB_INCSR_UNDERRUN 0x04
#define USB_INCSR_FFNOTEMPT 0x02
#define USB_INCSR_INPKTRDY 0x01
#define USB_OUTCSRH_AUTOCLR 0x80
#define USB_OUTCSRH_ISO 0x40
#define USB_OUTCSRH_DMAREQENAB 0x20
#define USB_OUTCSRH_DNYT 0x10
#define USB_OUTCSRH_DMAREQMODE 0x08
#define USB_OUTCSRH_AUTOCLR 0x8000
#define USB_OUTCSRH_ISO 0x4000
#define USB_OUTCSRH_DMAREQENAB 0x2000
#define USB_OUTCSRH_DNYT 0x1000
#define USB_OUTCSRH_DMAREQMODE 0x0800
#define USB_OUTCSR_CDT 0x80
#define USB_OUTCSR_SENTSTALL 0x40
#define USB_OUTCSR_SENDSTALL 0x20
@ -2456,6 +2463,11 @@
#define USB_TEST_J 0x02
#define USB_TEST_K 0x04
#define USB_TEST_PACKET 0x08
#define USB_TEST_FORCE_HS 0x10
#define USB_TEST_FORCE_FS 0x20
#define USB_TEST_ALL ( USB_TEST_SE0NAK | USB_TEST_J \
| USB_TEST_K | USB_TEST_PACKET \
| USB_TEST_FORCE_HS | USB_TEST_FORCE_FS)
/* DMA control bits */
#define USB_CNTL_ENA 0x01

View file

@ -26,6 +26,7 @@
#include "nand_id.h"
#include "system.h"
#include "panic.h"
#include "kernel.h"
/*
* Standard NAND flash commands
@ -104,6 +105,7 @@ struct nand_param
static struct nand_info* chip_info = NULL;
static struct nand_param internal_param;
static struct mutex nand_mtx;
static inline void jz_nand_wait_ready(void)
{
@ -132,6 +134,8 @@ static inline void jz_nand_read_buf8(void *buf, int count)
static void jz_nand_write_dma(void *source, unsigned int len, int bw)
{
mutex_lock(&nand_mtx);
if(((unsigned int)source < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)source, len);
@ -146,10 +150,14 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES);
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
mutex_unlock(&nand_mtx);
}
static void jz_nand_read_dma(void *target, unsigned int len, int bw)
{
mutex_lock(&nand_mtx);
if(((unsigned int)target < 0xa0000000) && len)
dma_cache_wback_inv((unsigned long)target, len);
@ -163,6 +171,8 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) = (DMAC_DCCSR_EN | DMAC_DCCSR_NDES);
while( REG_DMAC_DTCR(DMA_NAND_CHANNEL) )
yield();
mutex_unlock(&nand_mtx);
}
static inline void jz_nand_read_buf(void *buf, int count, int bw)
@ -433,6 +443,8 @@ static int jz_nand_init(void)
internal_param.oob_size = chip_info->page_size/32;
internal_param.page_per_block = chip_info->pages_per_block;
mutex_init(&nand_mtx);
return 0;
}

View file

@ -21,6 +21,7 @@
#include "config.h"
#include "jz4740.h"
#include "system.h"
static unsigned short codec_volume;
static unsigned short codec_base_gain;
@ -29,6 +30,8 @@ static bool HP_on_off_flag;
static int HP_register_value;
static int IS_WRITE_PCM;
static void i2s_codec_set_samplerate(unsigned short rate);
static void i2s_codec_clear(void)
{
REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL |
@ -38,11 +41,11 @@ static void i2s_codec_clear(void)
static void i2s_codec_init(void)
{
__aic_enable();
__aic_select_i2s();
__i2s_internal_codec();
__aic_enable();
__i2s_set_oss_sample_size(16);
REG_ICDC_CDCCR1 = (ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_PDVR | ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_VRCGL |
@ -55,14 +58,32 @@ static void i2s_codec_init(void)
//REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) |
REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) |
ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_6));
REG_ICDC_CDCCR1 &= 0xfffffffc;
mdelay(15);
REG_ICDC_CDCCR1 &= 0xffecffff;
REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG);
mdelay(600);
REG_ICDC_CDCCR1 &= 0xfff7ecff;
mdelay(2);
/* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~((1 << 29) | (1 << 28) | (1 << 26) | (1 << 27) | (1 << 14))) | ((1 << 24) | (1 << 25));
REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x3)) | 3);
i2s_codec_set_samplerate(44100);
HP_on_off_flag = 0; /* HP is off */
}
static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */
{
v = v & 0xff;
if(v < 0)
v = 0;
v &= 0xff;
if(v > 100)
v = 100;
codec_mic_gain = 31 * v/100;
@ -72,9 +93,8 @@ static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */
static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */
{
v = v & 0xff;
if(v < 0)
v = 0;
v &= 0xff;
if(v > 100)
v = 100;
@ -92,9 +112,8 @@ static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */
static void i2s_codec_set_volume(unsigned short v) /* 0 <= v <= 100 */
{
v = v & 0xff;
if(v < 0)
v = 0;
v &= 0xff;
if(v > 100)
v = 100;
@ -114,6 +133,7 @@ static unsigned short i2s_codec_get_bass(void)
{
unsigned short val;
int ret;
if(codec_base_gain == 0)
val = 0;
if(codec_base_gain == 1)
@ -124,7 +144,9 @@ static unsigned short i2s_codec_get_bass(void)
val = 75;
ret = val << 8;
val = val | ret;
val |= ret;
return val;
}
static unsigned short i2s_codec_get_mic(void)
@ -133,7 +155,9 @@ static unsigned short i2s_codec_get_mic(void)
int ret;
val = 100 * codec_mic_gain / 31;
ret = val << 8;
val = val | ret;
val |= ret;
return val;
}
static unsigned short i2s_codec_get_volume(void)
@ -151,7 +175,8 @@ static unsigned short i2s_codec_get_volume(void)
val = 75;
ret = val << 8;
val = val | ret;
val |= ret;
return val;
}
@ -271,10 +296,15 @@ void audiohw_mute(bool mute)
void audiohw_preinit(void)
{
i2s_reset();
i2s_codec_init();
}
void audiohw_postinit(void)
{
audiohw_mute(false);
}
void audiohw_init(void)
{
}

View file

@ -26,15 +26,14 @@
#include "system.h"
#include "kernel.h"
static volatile bool _lcd_on = false;
static volatile bool lcd_poweroff = false;
static volatile bool lcd_is_on = false;
static struct mutex lcd_mtx;
/* LCD init */
void lcd_init_device(void)
{
lcd_init_controller();
_lcd_on = true;
lcd_is_on = true;
mutex_init(&lcd_mtx);
}
@ -48,16 +47,16 @@ void lcd_enable(bool state)
else
lcd_off();
_lcd_on = state;
lcd_is_on = state;
}
bool lcd_enabled(void)
{
return _lcd_on;
return lcd_is_on;
}
/* Don't switch threads when in interrupt mode! */
static void lcd_lock(void)
static inline void lcd_lock(void)
{
if(LIKELY(!in_interrupt_mode()))
mutex_lock(&lcd_mtx);
@ -65,10 +64,19 @@ static void lcd_lock(void)
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
}
static void lcd_unlock(void)
static inline void lcd_unlock(void)
{
if(LIKELY(!in_interrupt_mode()))
mutex_unlock(&lcd_mtx);
}
static inline void lcd_wait(void)
{
if(LIKELY(!in_interrupt_mode()))
{
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
yield();
}
else
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
}
@ -98,13 +106,7 @@ void lcd_update_rect(int x, int y, int width, int height)
REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN;
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN;
if(LIKELY(!in_interrupt_mode()))
{
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) )
yield();
}
else
while( !(REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT));
lcd_wait();
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN;
@ -119,7 +121,7 @@ void lcd_update_rect(int x, int y, int width, int height)
This must be called after all other LCD functions that change the display. */
void lcd_update(void)
{
if (!_lcd_on)
if (!lcd_is_on)
return;
lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);

View file

@ -25,6 +25,7 @@
#include "button.h"
#include "button-target.h"
#include "powermgmt.h"
#include "kernel.h"
#define BTN_OFF (1 << 29)
#define BTN_VOL_DOWN (1 << 27)
@ -36,21 +37,22 @@
#define TS_AD_COUNT 5
#define M_SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
#define SADC_CFG_SNUM ((TS_AD_COUNT - 1) << SADC_CFG_SNUM_BIT)
#define SADC_CFG_INIT ( \
(2 << SADC_CFG_CLKOUT_NUM_BIT) | \
SADC_CFG_XYZ1Z2 | \
M_SADC_CFG_SNUM | \
SADC_CFG_SNUM | \
(2 << SADC_CFG_CLKDIV_BIT) | \
SADC_CFG_PBAT_HIGH | \
SADC_CFG_CMD_INT_PEN \
)
static short x_pos = -1, y_pos = -1, datacount = 0;
static signed int x_pos, y_pos;
static int datacount = 0, cur_touch = 0;
static bool pen_down = false;
static int cur_touch = 0;
static unsigned short bat_val = 0;
static volatile unsigned short bat_val = 0;
static struct mutex battery_mtx;
static enum touchscreen_mode current_mode = TOUCHSCREEN_POINT;
static const int touchscreen_buttons[3][3] =
@ -93,15 +95,21 @@ const unsigned short percent_to_volt_charge[11] =
unsigned int battery_adc_voltage(void)
{
register unsigned short dummy;
mutex_lock(&battery_mtx);
dummy = REG_SADC_BATDAT;
dummy = REG_SADC_BATDAT;
bat_val = 0;
REG_SADC_ENA |= SADC_ENA_PBATEN;
/* Primitive wakeup event */
while(bat_val == 0)
yield();
mutex_unlock(&battery_mtx);
return (bat_val*BATTERY_SCALE_FACTOR)>>12;
}
@ -127,6 +135,8 @@ void button_init_device(void)
__gpio_as_input(32*3 + 16);
__gpio_as_input(32*3 + 1);
__gpio_as_input(32*3 + 0);
mutex_init(&battery_mtx);
}
static int touch_to_pixels(short x, short y)
@ -162,6 +172,7 @@ int button_read_device(int *data)
{
int ret = 0, tmp;
/* Filter button events out if HOLD button is pressed at firmware/ level */
if((~REG_GPIO_PXPIN(3)) & BTN_HOLD)
return 0;
@ -186,7 +197,7 @@ int button_read_device(int *data)
else if(pen_down)
{
ret |= BUTTON_TOUCH;
if(data != NULL)
if(data != NULL && cur_touch != 0)
*data = cur_touch;
}
@ -226,18 +237,16 @@ void SADC(void)
REG_SADC_CTRL &= (~SADC_CTRL_PENDM );
REG_SADC_CTRL |= SADC_CTRL_PENUM;
pen_down = false;
x_pos = -1;
y_pos = -1;
datacount = 0;
cur_touch = 0;
}
if(state & SADC_CTRL_TSRDYM)
{
unsigned int dat;
unsigned short xData, yData;
short tsz1Data, tsz2Data;
signed short tsz1Data, tsz2Data;
dat = REG_SADC_TSDAT;
xData = (dat >> 0) & 0xFFF;
yData = (dat >> 16) & 0xFFF;
@ -245,34 +254,30 @@ void SADC(void)
tsz1Data = (dat >> 0) & 0xFFF;
tsz2Data = (dat >> 16) & 0xFFF;
if( !pen_down )
if(!pen_down)
return;
tsz1Data = tsz2Data - tsz1Data;
if((tsz1Data > 15) || (tsz1Data < -15))
if((tsz1Data > 100) || (tsz1Data < -100))
{
if(x_pos == -1)
if(datacount == 0)
{
x_pos = xData;
else
x_pos = (x_pos + xData) / 2;
if(y_pos == -1)
y_pos = yData;
}
else
y_pos = (y_pos + yData) / 2;
{
x_pos += xData;
y_pos += yData;
}
}
datacount++;
if(datacount > TS_AD_COUNT - 1)
if(datacount >= TS_AD_COUNT)
{
if(x_pos != -1)
{
cur_touch = touch_to_pixels(x_pos, y_pos);
x_pos = -1;
y_pos = -1;
}
cur_touch = touch_to_pixels(x_pos/datacount, y_pos/datacount);
datacount = 0;
}
}

View file

@ -24,23 +24,19 @@
#include "config.h"
#define __gpio_as_usb_detect() \
do { \
REG_GPIO_PXFUNS(3) = 0x10000000; \
REG_GPIO_PXSELS(3) = 0x10000000; \
REG_GPIO_PXPES(3) = 0x10000000; \
} while (0)
#define GPIO_UDC_DETE (32 * 3 + 28)
#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE)
static inline void usb_init_gpio(void)
{
__gpio_as_usb_detect();
system_enable_irq(IRQ_UDC);
__gpio_as_input(GPIO_UDC_DETE);
#define USB_INIT_GPIO() \
{ \
REG_GPIO_PXFUNS(3) = 0x10000000; \
REG_GPIO_PXSELS(3) = 0x10000000; \
REG_GPIO_PXPES(3) = 0x10000000; \
__gpio_as_input(GPIO_UDC_DETE); \
}
#define USB_DRV_CONNECTED() (__gpio_get_pin(GPIO_UDC_DETE) == 1)
int usb_detect(void);
void usb_init_device(void);
bool usb_drv_connected(void);

View file

@ -27,13 +27,14 @@
#include "pcm.h"
#include "jz4740.h"
/****************************************************************************
** Playback DMA transfer
**/
void pcm_postinit(void)
{
audiohw_postinit(); /* implemented not for all codecs */
audiohw_postinit();
pcm_apply_settings();
}
@ -61,29 +62,55 @@ void pcm_set_frequency(unsigned int frequency)
{
(void) frequency;
/* TODO */
/*
__i2s_set_oss_sample_size(frequency);
i2s_codec_set_samplerate(frequency);
*/
}
static void play_start_pcm(void)
{
pcm_apply_settings();
/* TODO */
__aic_enable_transmit_dma();
__aic_enable_replay();
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
}
static void play_stop_pcm(void)
{
/* TODO */
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN;
__aic_disable_transmit_dma();
__aic_disable_replay();
}
void pcm_play_dma_start(const void *addr, size_t size)
{
(void)addr;
(void)size;
/* TODO */
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = 0;
REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = ( DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_32
| DMAC_DCMD_TIE);
play_start_pcm();
}
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
{
if( REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT )
__aic_disable_transmit_dma();
}
size_t pcm_get_bytes_waiting(void)
{
return REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL);
}
void pcm_play_dma_stop(void)
{
play_stop_pcm();
@ -110,12 +137,6 @@ void pcm_play_dma_pause(bool pause)
}
size_t pcm_get_bytes_waiting(void)
{
/* TODO */
return 0;
}
#ifdef HAVE_RECORDING
/* TODO */
void pcm_rec_dma_init(void)

View file

@ -372,7 +372,7 @@ static char* parse_exception(unsigned int cause)
}
void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
{
{
panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr);
}

View file

@ -108,4 +108,7 @@ bool in_interrupt_mode(void);
#define DMA_USB_CHANNEL 2
#define DMA_AIC_TX_CHANNEL 3
#define XDMA_CALLBACK(n) DMA ## n
#define DMA_CALLBACK(n) XDMA_CALLBACK(n)
#endif /* __SYSTEM_TARGET_H_ */

File diff suppressed because it is too large Load diff