Onda VX747:
* Implement lcd_flip() * Add support for multiple banks in NAND driver * Add basic I²C driver (untested) * Get audio back working * Add power driver * Other minor fixes and cleanups git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19863 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
95577c7996
commit
a4e7bc383e
13 changed files with 471 additions and 105 deletions
|
@ -1220,6 +1220,7 @@ target/mips/ingenic_jz47xx/ata-nand-jz4740.c
|
|||
target/mips/ingenic_jz47xx/ata-sd-jz4740.c
|
||||
target/mips/ingenic_jz47xx/codec-jz4740.c
|
||||
target/mips/ingenic_jz47xx/kernel-jz4740.c
|
||||
target/mips/ingenic_jz47xx/i2c-jz4740.c
|
||||
target/mips/ingenic_jz47xx/lcd-jz4740.c
|
||||
target/mips/ingenic_jz47xx/pcm-jz4740.c
|
||||
target/mips/ingenic_jz47xx/system-jz4740.c
|
||||
|
@ -1231,6 +1232,7 @@ drivers/nand_id.c
|
|||
target/mips/ingenic_jz47xx/onda_vx747/backlight-onda_vx747.c
|
||||
target/mips/ingenic_jz47xx/onda_vx747/lcd-onda_vx747.c
|
||||
target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
|
||||
target/mips/ingenic_jz47xx/onda_vx747/power-onda_vx747.c
|
||||
#endif
|
||||
|
||||
#ifdef ONDA_VX767
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
/* Hardware controlled charging with monitoring */
|
||||
//#define CONFIG_CHARGING CHARGING_MONITOR
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
|
|
|
@ -3381,13 +3381,17 @@ static __inline__ unsigned int __cpm_get_pllout(void)
|
|||
unsigned long m, n, no, pllout;
|
||||
unsigned long cppcr = REG_CPM_CPPCR;
|
||||
unsigned long od[4] = {1, 2, 2, 4};
|
||||
if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
|
||||
|
||||
if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP))
|
||||
{
|
||||
m = __cpm_get_pllm() + 2;
|
||||
n = __cpm_get_plln() + 2;
|
||||
no = od[__cpm_get_pllod()];
|
||||
pllout = ((JZ_EXTAL) / (n * no)) * m;
|
||||
} else
|
||||
}
|
||||
else
|
||||
pllout = JZ_EXTAL;
|
||||
|
||||
return pllout;
|
||||
}
|
||||
|
||||
|
@ -3447,23 +3451,19 @@ static __inline__ unsigned int __cpm_get_pixclk(void)
|
|||
/* I2S clock */
|
||||
static __inline__ unsigned int __cpm_get_i2sclk(void)
|
||||
{
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) {
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_I2CS)
|
||||
return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
|
||||
}
|
||||
else {
|
||||
else
|
||||
return JZ_EXTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* USB clock */
|
||||
static __inline__ unsigned int __cpm_get_usbclk(void)
|
||||
{
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_UCS) {
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_UCS)
|
||||
return __cpm_get_pllout2() / (__cpm_get_udiv() + 1);
|
||||
}
|
||||
else {
|
||||
else
|
||||
return JZ_EXTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* MSC clock */
|
||||
|
@ -3492,12 +3492,10 @@ static inline void __cpm_select_msc_clk(int sd)
|
|||
unsigned int pllout2 = __cpm_get_pllout2();
|
||||
unsigned int div = 0;
|
||||
|
||||
if (sd) {
|
||||
if (sd)
|
||||
div = pllout2 / 24000000;
|
||||
}
|
||||
else {
|
||||
else
|
||||
div = pllout2 / 16000000;
|
||||
}
|
||||
|
||||
REG_CPM_MSCCDR = div - 1;
|
||||
}
|
||||
|
@ -3510,12 +3508,11 @@ static inline void __cpm_select_msc_hs_clk(int sd)
|
|||
unsigned int pllout2 = __cpm_get_pllout2();
|
||||
unsigned int div = 0;
|
||||
|
||||
if (sd) {
|
||||
if (sd)
|
||||
div = pllout2 / 48000000;
|
||||
}
|
||||
else {
|
||||
else
|
||||
div = pllout2 / 16000000;
|
||||
}
|
||||
|
||||
REG_CPM_MSCCDR = div - 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,21 +85,20 @@ struct nand_param
|
|||
*
|
||||
*/
|
||||
|
||||
#define NAND_DATAPORT 0xB8000000
|
||||
#define NAND_ADDRPORT 0xB8010000
|
||||
#define NAND_COMMPORT 0xB8008000
|
||||
static volatile unsigned long nand_address;
|
||||
#define NAND_DATAPORT (nand_address)
|
||||
#define NAND_ADDRPORT (nand_address+0x10000)
|
||||
#define NAND_COMMPORT (nand_address+0x08000)
|
||||
|
||||
#define ECC_BLOCK 512
|
||||
#define ECC_POS 6
|
||||
#define PAR_SIZE 9
|
||||
#define ECC_BLOCK 512
|
||||
#define ECC_POS 6
|
||||
#define PAR_SIZE 9
|
||||
|
||||
#define __nand_cmd(n) (REG8(NAND_COMMPORT) = (n))
|
||||
#define __nand_addr(n) (REG8(NAND_ADDRPORT) = (n))
|
||||
#define __nand_data8() (REG8(NAND_DATAPORT))
|
||||
#define __nand_data16() (REG16(NAND_DATAPORT))
|
||||
|
||||
#define __nand_enable() (REG_EMC_NFCSR |= EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1)
|
||||
#define __nand_disable() (REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1))
|
||||
#define __nand_ecc_rs_encoding() \
|
||||
(REG_EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_ERST | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING)
|
||||
#define __nand_ecc_rs_decoding() \
|
||||
|
@ -111,6 +110,9 @@ struct nand_param
|
|||
/*--------------------------------------------------------------*/
|
||||
|
||||
static struct nand_info* chip_info = NULL;
|
||||
static struct nand_info* banks[4];
|
||||
static unsigned int nr_banks = 1;
|
||||
static unsigned long bank_size;
|
||||
static struct nand_param internal_param;
|
||||
#ifdef USE_DMA
|
||||
static struct mutex nand_mtx;
|
||||
|
@ -344,6 +346,9 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
|
|||
int i, j;
|
||||
unsigned char *data_buf;
|
||||
unsigned char oob_buf[nandp->oob_size];
|
||||
|
||||
if(nand_address == 0)
|
||||
return -1;
|
||||
|
||||
page_size = nandp->page_size;
|
||||
oob_size = nandp->oob_size;
|
||||
|
@ -462,45 +467,113 @@ static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable NAND controller
|
||||
*/
|
||||
static void jz_nand_enable(void)
|
||||
{
|
||||
__nand_enable();
|
||||
|
||||
REG_EMC_SMCR1 = 0x04444400;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable NAND controller
|
||||
*/
|
||||
static void jz_nand_disable(void)
|
||||
{
|
||||
__nand_disable();
|
||||
REG_EMC_NFCSR &= ~(EMC_NFCSR_NFCE1 | EMC_NFCSR_NFCE2 |
|
||||
EMC_NFCSR_NFCE3 | EMC_NFCSR_NFCE4 |
|
||||
EMC_NFCSR_NFE1 | EMC_NFCSR_NFE2 |
|
||||
EMC_NFCSR_NFE3 | EMC_NFCSR_NFE4 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable NAND controller
|
||||
*/
|
||||
static void jz_nand_enable(void)
|
||||
{
|
||||
#if 0
|
||||
/* OF RE */
|
||||
REG_GPIO_PXFUNS(1) = 0x1E018000; // __gpio_as_func0() start
|
||||
REG_GPIO_PXSELC(1) = 0x1E018000; // __gpio_as_func0() end
|
||||
|
||||
REG_GPIO_PXFUNS(2) = 0x3000<<16; // __gpio_as_func0() start
|
||||
REG_GPIO_PXSELC(2) = 0x3000<<16; // __gpio_as_func0() end
|
||||
|
||||
REG_GPIO_PXFUNC(2) = 0x4000<<16; // __gpio_port_as_input() start
|
||||
REG_GPIO_PXSELC(2) = 0x4000<<16;
|
||||
REG_GPIO_PXDIRC(2) = 0x4000<<16; // __gpio_port_as_input() end
|
||||
REG_GPIO_PXPES(2) = 0x4000<<16; // __gpio_disable_pull()
|
||||
|
||||
REG_GPIO_PXFUNS(1) = 0x40<<16; // __gpio_as_func0() start
|
||||
REG_GPIO_PXSELC(1) = 0x40<<16; // __gpio_as_func0() end
|
||||
|
||||
REG_EMC_SMCR1 = (REG_EMC_SMCR1 & 0xFF) | 0x4621200;
|
||||
REG_EMC_SMCR2 = (REG_EMC_SMCR2 & 0xFF) | 0x4621200;
|
||||
REG_EMC_SMCR3 = (REG_EMC_SMCR3 & 0xFF) | 0x4621200;
|
||||
REG_EMC_SMCR4 = (REG_EMC_SMCR4 & 0xFF) | 0x4621200;
|
||||
|
||||
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x6621200;
|
||||
#else
|
||||
REG_EMC_SMCR1 = REG_EMC_SMCR2 = REG_EMC_SMCR3 = REG_EMC_SMCR4 = 0x04444400;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void jz_nand_select(int bank)
|
||||
{
|
||||
REG_EMC_NFCSR |= (EMC_NFCSR_NFE(bank+1) | EMC_NFCSR_NFCE(bank+1));
|
||||
|
||||
switch(bank)
|
||||
{
|
||||
case 0:
|
||||
nand_address = 0xB8000000;
|
||||
break;
|
||||
case 1:
|
||||
nand_address = 0xB4000000;
|
||||
break;
|
||||
case 2:
|
||||
nand_address = 0xAC000000;
|
||||
break;
|
||||
case 3:
|
||||
nand_address = 0xA8000000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void jz_nand_deselect(int bank)
|
||||
{
|
||||
REG_EMC_NFCSR &= ~(EMC_NFCSR_NFE(bank+1) | EMC_NFCSR_NFCE(bank+1));
|
||||
nand_address = 0;
|
||||
}
|
||||
|
||||
static int jz_nand_init(void)
|
||||
{
|
||||
unsigned char cData[5];
|
||||
int i;
|
||||
|
||||
jz_nand_enable();
|
||||
|
||||
__nand_cmd(NAND_CMD_READID);
|
||||
__nand_addr(NAND_CMD_READ0);
|
||||
cData[0] = __nand_data8();
|
||||
cData[1] = __nand_data8();
|
||||
cData[2] = __nand_data8();
|
||||
cData[3] = __nand_data8();
|
||||
cData[4] = __nand_data8();
|
||||
|
||||
chip_info = nand_identify(cData);
|
||||
if(chip_info == NULL)
|
||||
for(i=0; i<4; i++)
|
||||
{
|
||||
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
||||
cData[1], cData[2], cData[3], cData[4]);
|
||||
return -1; /* panicf() doesn't return though */
|
||||
jz_nand_select(i);
|
||||
|
||||
__nand_cmd(NAND_CMD_READID);
|
||||
__nand_addr(NAND_CMD_READ0);
|
||||
cData[0] = __nand_data8();
|
||||
cData[1] = __nand_data8();
|
||||
cData[2] = __nand_data8();
|
||||
cData[3] = __nand_data8();
|
||||
cData[4] = __nand_data8();
|
||||
|
||||
jz_nand_deselect(i);
|
||||
|
||||
logf("NAND chip %d: 0x%x 0x%x 0x%x 0x%x 0x%x", i+1, cData[0], cData[1],
|
||||
cData[2], cData[3], cData[4]);
|
||||
|
||||
banks[i] = nand_identify(cData);
|
||||
|
||||
if(banks[i] != NULL)
|
||||
nr_banks++;
|
||||
|
||||
if(i == 0 && banks[i] == NULL)
|
||||
{
|
||||
panicf("Unknown NAND flash chip: 0x%x 0x%x 0x%x 0x%x 0x%x", cData[0],
|
||||
cData[1], cData[2], cData[3], cData[4]);
|
||||
return -1; /* panicf() doesn't return though */
|
||||
}
|
||||
}
|
||||
chip_info = banks[0];
|
||||
|
||||
internal_param.bus_width = 8;
|
||||
internal_param.row_cycle = chip_info->row_cycles;
|
||||
|
@ -508,13 +581,17 @@ static int jz_nand_init(void)
|
|||
internal_param.oob_size = chip_info->spare_size;
|
||||
internal_param.page_per_block = chip_info->pages_per_block;
|
||||
|
||||
bank_size = chip_info->page_size * chip_info->blocks_per_bank / 512 * chip_info->pages_per_block;
|
||||
|
||||
jz_nand_disable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool inited = false;
|
||||
int nand_init(void)
|
||||
{
|
||||
int res = 0;
|
||||
static bool inited = false;
|
||||
|
||||
if(!inited)
|
||||
{
|
||||
|
@ -533,29 +610,37 @@ int nand_init(void)
|
|||
|
||||
int nand_read_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf)
|
||||
{
|
||||
int i, ret = 0;
|
||||
int i, ret = 0, chip_size = chip_info->page_size;
|
||||
|
||||
logf("nand_read_sectors(%ld, %d, 0x%x)", start, count, (int)buf);
|
||||
|
||||
start *= 512;
|
||||
count *= 512;
|
||||
|
||||
if(count <= chip_info->page_size)
|
||||
if(count <= chip_size)
|
||||
{
|
||||
ret = jz_nand_read_page(start/chip_info->page_size, temp_page);
|
||||
memcpy(buf, temp_page+(start%chip_info->page_size), count);
|
||||
return ret;
|
||||
jz_nand_select(start / 512 / bank_size);
|
||||
|
||||
ret = jz_nand_read_page(start/chip_size, temp_page);
|
||||
memcpy(buf, temp_page+(start%chip_size), count);
|
||||
|
||||
jz_nand_deselect(start / 512 / bank_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0; i<count && ret==0; i+=chip_info->page_size)
|
||||
for(i=0; i<count && ret==0; i+=chip_size)
|
||||
{
|
||||
ret = jz_nand_read_page((start+i)/chip_info->page_size, temp_page);
|
||||
memcpy(buf+i, temp_page+((start+i)%chip_info->page_size),
|
||||
(count-i < chip_info->page_size ? count-i : chip_info->page_size));
|
||||
jz_nand_select((start/512+i) / bank_size);
|
||||
|
||||
ret = jz_nand_read_page((start+i)/chip_size, temp_page);
|
||||
memcpy(buf+i, temp_page+((start+i)%chip_size),
|
||||
(count-i < chip_size ? count-i : chip_size));
|
||||
|
||||
jz_nand_deselect((start/512+i) / bank_size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
|
@ -605,6 +690,7 @@ void nand_enable(bool on)
|
|||
void nand_get_info(IF_MV2(int drive,) struct storage_info *info)
|
||||
{
|
||||
(void)drive;
|
||||
|
||||
/* firmware version */
|
||||
info->revision="0.00";
|
||||
|
||||
|
@ -612,8 +698,7 @@ void nand_get_info(IF_MV2(int drive,) struct storage_info *info)
|
|||
info->product="NAND Storage";
|
||||
|
||||
/* blocks count */
|
||||
/* TODO: proper amount of sectors! */
|
||||
info->num_sectors = ((chip_info->page_size+chip_info->spare_size) / 512) * chip_info->pages_per_block * chip_info->blocks_per_bank;
|
||||
info->num_sectors = bank_size * nr_banks;
|
||||
info->sector_size = 512;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,9 +38,7 @@ static struct wakeup sd_wakeup;
|
|||
|
||||
#define DEBUG(x...) logf(x);
|
||||
|
||||
#ifdef MMC_CD_PIN
|
||||
#define MMC_INSERT_STATUS() __gpio_get_pin(MMC_CD_PIN)
|
||||
#endif
|
||||
|
||||
#define MMC_RESET() __msc_reset()
|
||||
|
||||
|
@ -367,7 +365,7 @@ struct mmc_request
|
|||
|
||||
static int use_4bit; /* Use 4-bit data bus */
|
||||
static int num_6;
|
||||
static int sd2_0;
|
||||
static int sd2_0 = 1;
|
||||
|
||||
/* Stop the MMC clock and wait while it happens */
|
||||
static inline int jz_mmc_stop_clock(void)
|
||||
|
@ -766,7 +764,7 @@ static int jz_mmc_exec_cmd(struct mmc_request *request)
|
|||
jz_mmc_stop_clock();
|
||||
|
||||
/* mask all interrupts */
|
||||
//REG_MSC_IMASK = 0xffff;
|
||||
REG_MSC_IMASK = 0xffff;
|
||||
/* clear status */
|
||||
REG_MSC_IREG = 0xffff;
|
||||
/*open interrupt */
|
||||
|
@ -812,7 +810,6 @@ static int jz_mmc_exec_cmd(struct mmc_request *request)
|
|||
case 6:
|
||||
if (num_6 < 2)
|
||||
{
|
||||
|
||||
#if defined(MMC_DMA_ENABLE)
|
||||
cmdat |=
|
||||
MSC_CMDAT_DATA_EN | MSC_CMDAT_READ |
|
||||
|
@ -992,10 +989,7 @@ static int jz_mmc_exec_cmd(struct mmc_request *request)
|
|||
********************************************************************************************************************/
|
||||
static int jz_mmc_chkcard(void)
|
||||
{
|
||||
if (MMC_INSERT_STATUS() == 0)
|
||||
return 1; /* insert entirely */
|
||||
else
|
||||
return 0; /* not insert entirely */
|
||||
return (MMC_INSERT_STATUS() == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
#if MMC_DMA_INTERRUPT
|
||||
|
@ -1044,13 +1038,13 @@ void MSC(void)
|
|||
static void jz_mmc_hardware_init(void)
|
||||
{
|
||||
mmc_init_gpio(); /* init GPIO */
|
||||
__cpm_start_msc(); /* enable mmc clock */
|
||||
#ifdef MMC_POWER_ON
|
||||
MMC_POWER_ON(); /* turn on power of card */
|
||||
#endif
|
||||
MMC_RESET(); /* reset mmc/sd controller */
|
||||
MMC_IRQ_MASK(); /* mask all IRQs */
|
||||
jz_mmc_stop_clock(); /* stop MMC/SD clock */
|
||||
__cpm_start_msc();
|
||||
#ifdef MMC_DMA_ENABLE
|
||||
// __cpm_start_dmac();
|
||||
// __dmac_enable_module();
|
||||
|
@ -1101,7 +1095,7 @@ int _sd_init(void)
|
|||
|
||||
bool card_detect_target(void)
|
||||
{
|
||||
return jz_mmc_chkcard() == 1;
|
||||
return (jz_mmc_chkcard() == 1);
|
||||
}
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
|
|
|
@ -28,7 +28,6 @@ static unsigned short codec_base_gain;
|
|||
static unsigned short codec_mic_gain;
|
||||
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);
|
||||
|
||||
|
@ -44,6 +43,9 @@ static void i2s_codec_reset(void)
|
|||
|
||||
static void i2s_codec_init(void)
|
||||
{
|
||||
__cpm_start_aic1();
|
||||
__cpm_start_aic2();
|
||||
|
||||
__aic_enable();
|
||||
|
||||
__i2s_internal_codec();
|
||||
|
@ -185,7 +187,6 @@ static unsigned short i2s_codec_get_volume(void)
|
|||
static void i2s_codec_set_samplerate(unsigned short rate)
|
||||
{
|
||||
unsigned short speed = 0;
|
||||
unsigned short val = 0;
|
||||
|
||||
switch (rate)
|
||||
{
|
||||
|
|
240
firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
Normal file
240
firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 by Maurus Cuelenaere
|
||||
*
|
||||
* based on linux/arch/mips/jz4740/i2c.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Jz4740 I2C routines.
|
||||
*
|
||||
* Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
|
||||
* Author: <lhhuang@ingenic.cn>
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "jz4740.h"
|
||||
#include "logf.h"
|
||||
#include "generic_i2c.h"
|
||||
|
||||
|
||||
/* I2C protocol */
|
||||
#define I2C_READ 1
|
||||
#define I2C_WRITE 0
|
||||
|
||||
#define TIMEOUT 1000
|
||||
|
||||
/*
|
||||
* I2C bus protocol basic routines
|
||||
*/
|
||||
static int i2c_put_data(unsigned char data)
|
||||
{
|
||||
unsigned int timeout = TIMEOUT*10;
|
||||
|
||||
__i2c_write(data);
|
||||
__i2c_set_drf();
|
||||
while (__i2c_check_drf() != 0);
|
||||
while (!__i2c_transmit_ended());
|
||||
while (!__i2c_received_ack() && timeout)
|
||||
timeout--;
|
||||
|
||||
if (timeout)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int i2c_put_data_nack(unsigned char data)
|
||||
{
|
||||
unsigned int timeout = TIMEOUT*10;
|
||||
|
||||
__i2c_write(data);
|
||||
__i2c_set_drf();
|
||||
while (__i2c_check_drf() != 0);
|
||||
while (!__i2c_transmit_ended());
|
||||
while (timeout--);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_get_data(unsigned char *data, int ack)
|
||||
{
|
||||
int timeout = TIMEOUT*10;
|
||||
|
||||
if (!ack)
|
||||
__i2c_send_nack();
|
||||
else
|
||||
__i2c_send_ack();
|
||||
|
||||
while (__i2c_check_drf() == 0 && timeout)
|
||||
timeout--;
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
if (!ack)
|
||||
__i2c_send_stop();
|
||||
*data = __i2c_read();
|
||||
__i2c_clear_drf();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* I2C interface
|
||||
*/
|
||||
void i2c_open(void)
|
||||
{
|
||||
/* TODO */
|
||||
//__i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */
|
||||
__i2c_enable();
|
||||
}
|
||||
|
||||
void i2c_close(void)
|
||||
{
|
||||
udelay(300); /* wait for STOP goes over. */
|
||||
__i2c_disable();
|
||||
}
|
||||
|
||||
void i2c_setclk(unsigned int i2cclk)
|
||||
{
|
||||
/* TODO */
|
||||
//__i2c_set_clk(jz_clocks.extalclk, i2cclk);
|
||||
}
|
||||
|
||||
int i2c_read(int device, unsigned char *buf, int count)
|
||||
{
|
||||
int cnt = count;
|
||||
int timeout = 5;
|
||||
|
||||
device &= 0xFF;
|
||||
|
||||
L_try_again:
|
||||
if (timeout < 0)
|
||||
goto L_timeout;
|
||||
|
||||
__i2c_send_nack(); /* Master does not send ACK, slave sends it */
|
||||
|
||||
__i2c_send_start();
|
||||
if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
|
||||
goto device_err;
|
||||
|
||||
__i2c_send_ack(); /* Master sends ACK for continue reading */
|
||||
|
||||
while (cnt)
|
||||
{
|
||||
if (cnt == 1)
|
||||
{
|
||||
if (i2c_get_data(buf, 0) < 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i2c_get_data(buf, 1) < 0)
|
||||
break;
|
||||
}
|
||||
cnt--;
|
||||
buf++;
|
||||
}
|
||||
|
||||
__i2c_send_stop();
|
||||
return count - cnt;
|
||||
|
||||
device_err:
|
||||
timeout--;
|
||||
__i2c_send_stop();
|
||||
goto L_try_again;
|
||||
|
||||
L_timeout:
|
||||
__i2c_send_stop();
|
||||
logf("Read I2C device 0x%2x failed.", device);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i2c_write(int device, unsigned char *buf, int count)
|
||||
{
|
||||
int cnt = count;
|
||||
int timeout = 5;
|
||||
|
||||
device &= 0xFF;
|
||||
|
||||
__i2c_send_nack(); /* Master does not send ACK, slave sends it */
|
||||
|
||||
W_try_again:
|
||||
if (timeout < 0)
|
||||
goto W_timeout;
|
||||
|
||||
cnt = count;
|
||||
|
||||
__i2c_send_start();
|
||||
if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
|
||||
goto device_err;
|
||||
|
||||
#if 0 //CONFIG_JZ_TPANEL_ATA2508
|
||||
if (address == 0xff)
|
||||
{
|
||||
while (cnt)
|
||||
{
|
||||
if (i2c_put_data_nack(*buf) < 0)
|
||||
break;
|
||||
cnt--;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (cnt)
|
||||
{
|
||||
if (i2c_put_data(*buf) < 0)
|
||||
break;
|
||||
cnt--;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
|
||||
__i2c_send_stop();
|
||||
return count - cnt;
|
||||
|
||||
device_err:
|
||||
timeout--;
|
||||
__i2c_send_stop();
|
||||
goto W_try_again;
|
||||
|
||||
W_timeout:
|
||||
logf("Write I2C device 0x%2x failed.", device);
|
||||
__i2c_send_stop();
|
||||
return -1;
|
||||
}
|
|
@ -39,7 +39,8 @@ void tick_start(unsigned int interval_in_ms)
|
|||
__tcu_select_extalclk(0);
|
||||
__tcu_select_clk_div4(0);
|
||||
|
||||
latch = (JZ_EXTAL / 4 + (interval_in_ms>>1)) / interval_in_ms;
|
||||
/* 12Mhz / 4 = 3Mhz */
|
||||
latch = interval_in_ms*1000 * 3;
|
||||
|
||||
REG_TCU_TCNT(0) = 0;
|
||||
REG_TCU_TDFR(0) = latch;
|
||||
|
|
|
@ -69,14 +69,6 @@ bool lcd_enabled(void)
|
|||
/* Update a fraction of the display. */
|
||||
void lcd_update_rect(int x, int y, int width, int height)
|
||||
{
|
||||
#if 1
|
||||
/* This is an ugly HACK until partial LCD drawing works.. */
|
||||
width = LCD_WIDTH;
|
||||
height = LCD_HEIGHT;
|
||||
x = 0;
|
||||
y = 0;
|
||||
#endif
|
||||
|
||||
mutex_lock(&lcd_mtx);
|
||||
|
||||
__cpm_start_lcd();
|
||||
|
|
|
@ -39,29 +39,12 @@ int _sd_write_sectors(unsigned long start, int count, const void* buf);
|
|||
int _sd_init(void);
|
||||
|
||||
#define MMC_CD_PIN (29 + 1 * 32) /* Pin to check card insertion */
|
||||
//#define MMC_POWER_PIN (22 + 2 * 32) /* Pin to enable/disable card power */
|
||||
|
||||
#ifdef MMC_POWER_PIN
|
||||
#define MMC_POWER_OFF() \
|
||||
do { \
|
||||
__gpio_clear_pin(MMC_POWER_PIN); \
|
||||
} while (0)
|
||||
|
||||
#define MMC_POWER_ON() \
|
||||
do { \
|
||||
__gpio_set_pin(MMC_POWER_PIN); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static inline void mmc_init_gpio(void)
|
||||
{
|
||||
__gpio_as_msc();
|
||||
__gpio_as_input(MMC_CD_PIN);
|
||||
#ifdef MMC_POWER_PIN
|
||||
__gpio_as_func0(MMC_POWER_PIN);
|
||||
__gpio_as_output(MMC_POWER_PIN);
|
||||
#endif
|
||||
__gpio_enable_pull(32*3+29);
|
||||
//__gpio_enable_pull(32*3+29);
|
||||
__gpio_enable_pull(32*3+10);
|
||||
__gpio_enable_pull(32*3+11);
|
||||
__gpio_enable_pull(32*3+12);
|
||||
|
|
|
@ -240,6 +240,34 @@ void lcd_set_target(short x, short y, short width, short height)
|
|||
SLCD_SET_COMMAND(REG_RW_GRAM); /* write data to GRAM */
|
||||
}
|
||||
|
||||
void lcd_set_flip(bool yesno)
|
||||
{
|
||||
int i;
|
||||
|
||||
__cpm_start_lcd();
|
||||
#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
|
||||
if(yesno)
|
||||
{
|
||||
SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_HWM));
|
||||
}
|
||||
else
|
||||
{
|
||||
SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_VID | ENTRY_MODE_HID | ENTRY_MODE_HWM));
|
||||
}
|
||||
#else
|
||||
if(yesno)
|
||||
{
|
||||
SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_HID | ENTRY_MODE_AM));
|
||||
}
|
||||
else
|
||||
{
|
||||
SLCD_SEND_COMMAND(REG_ENTRY_MODE, (ENTRY_MODE_BGR | ENTRY_MODE_VID | ENTRY_MODE_AM));
|
||||
}
|
||||
#endif
|
||||
DELAY;
|
||||
__cpm_stop_lcd();
|
||||
}
|
||||
|
||||
void lcd_on(void)
|
||||
{
|
||||
_display_on();
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 by Maurus Cuelenaere
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "power.h"
|
||||
#include "jz4740.h"
|
||||
|
||||
/* TQ7051 chip */
|
||||
#define USB_CHARGER_GPIO (32*1+30) /* STAT port */
|
||||
|
||||
/* Detect which power sources are present. */
|
||||
unsigned int power_input_status(void)
|
||||
{
|
||||
unsigned int status = 0;
|
||||
|
||||
if (__gpio_get_pin(USB_CHARGER_GPIO))
|
||||
status |= POWER_INPUT_USB_CHARGER;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
__gpio_as_input(USB_CHARGER_GPIO);
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#define GPIO_UDC_DETE (32 * 3 + 28)
|
||||
#define GPIO_UDC_DETE (32 * 3 + 28) /* A18 = ADP_CHK */
|
||||
#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE)
|
||||
#define USB_GPIO_IRQ GPIO124
|
||||
|
||||
|
|
Loading…
Reference in a new issue