Index: firmware/export/config-h10.h =================================================================== --- firmware/export/config-h10.h (revision 15552) +++ firmware/export/config-h10.h (working copy) @@ -12,7 +12,7 @@ #define HAVE_RECORDING /* Define bitmask of input sources - recordable bitmask can be defined explicitly if different */ -#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) /* define the bitmask of hardware sample rates */ #define HW_SAMPR_CAPS (SAMPR_CAP_44) @@ -85,8 +85,8 @@ #define AB_REPEAT_ENABLE 1 /* FM Tuner */ -/*#define CONFIG_TUNER TEA5767 -#define CONFIG_TUNER_XTAL 32768 *//* TODO: what is this? */ +#define CONFIG_TUNER TEA5767 +#define CONFIG_TUNER_XTAL 32768 /* Define this for LCD backlight available */ #define HAVE_BACKLIGHT Index: firmware/export/config-h10_5gb.h =================================================================== --- firmware/export/config-h10_5gb.h (revision 15552) +++ firmware/export/config-h10_5gb.h (working copy) @@ -12,7 +12,7 @@ #define HAVE_RECORDING /* Define bitmask of input sources - recordable bitmask can be defined explicitly if different */ -#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) /* define the bitmask of hardware sample rates */ #define HW_SAMPR_CAPS (SAMPR_CAP_44) @@ -71,8 +71,8 @@ #define AB_REPEAT_ENABLE 1 /* FM Tuner */ -/*#define CONFIG_TUNER TEA5767 -#define CONFIG_TUNER_XTAL 32768 *//* TODO: what is this? */ +#define CONFIG_TUNER TEA5767 +#define CONFIG_TUNER_XTAL 32768 /* Define this for LCD backlight available */ #define HAVE_BACKLIGHT Index: firmware/target/arm/audio-pp.c =================================================================== --- firmware/target/arm/audio-pp.c (revision 15552) +++ firmware/target/arm/audio-pp.c (working copy) @@ -35,6 +35,7 @@ /* Prevent pops from unneeded switching */ static int last_source = AUDIO_SRC_PLAYBACK; #ifdef HAVE_FMRADIO_REC + bool recording = flags & SRCF_RECORDING; static bool last_recording = false; #endif @@ -90,3 +91,5 @@ } /* audio_input_mux */ + + Index: firmware/target/arm/iriver/h10/power-h10.c =================================================================== --- firmware/target/arm/iriver/h10/power-h10.c (revision 15552) +++ firmware/target/arm/iriver/h10/power-h10.c (working copy) @@ -35,18 +35,25 @@ bool charger_enabled; #endif -#if 0 #if CONFIG_TUNER bool tuner_power(bool status) { (void)status; /* TODO: tuner power control */ - return true; + if(status==true) + { + /* switch recording input to the tuner */ + GPIOB_OUTPUT_VAL |= 0x04; + } + else + { + GPIOB_OUTPUT_VAL &= ~0x04; + } + return status; } #endif /* #if CONFIG_TUNER */ -#endif void power_init(void) { Index: firmware/drivers/fmradio_i2c.c =================================================================== --- firmware/drivers/fmradio_i2c.c (revision 15552) +++ firmware/drivers/fmradio_i2c.c (working copy) @@ -41,7 +41,7 @@ { return i2c_read(I2C_IFACE_0, address, buf, count); } -#else +#else /* IAUDIO_X5 */ /* cute little functions, atomic read-modify-write */ /* SDA is GPIO1,23 */ @@ -61,7 +61,7 @@ #define SCL_HI or_l( 0x01000000, &GPIO1_OUT) #define SCL ( 0x01000000 & GPIO1_READ) -#else +#else /* IRIVER_H300_SERIES */ /* SDA is GPIO55 */ #define SDA_OUTINIT and_l(~0x00800000, &GPIO1_OUT) @@ -75,8 +75,9 @@ #define SCL_LO and_l(~0x00000008, &GPIO_OUT) #define SCL_HI or_l( 0x00000008, &GPIO_OUT) #define SCL ( 0x00000008 & GPIO_READ) -#endif +#endif /* IRIVER_H300_SERIES */ + /* delay loop to achieve 400kHz at 120MHz CPU frequency */ #define DELAY \ ({ \ @@ -258,9 +259,214 @@ return x; } #endif /* ! IAUDIO_X5 */ -#else +#else /* CONFIG_I2C == I2C_COLDFIRE */ + +#ifdef IRIVER_H10 + /* cute little functions, atomic read-modify-write */ -/* SDA is PB4 */ +/* SDA is GPIOD.3 */ +#define SDA_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08) +#define SDA_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x08) +#define SDA_INPUT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08) +#define SDA_OUTPUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08) +#define SDA (GPIOD_OUTPUT_VAL & 0x08) + +#define SDA_HI_IN GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08);GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x08) +#define SDA_LO_OUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08);GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08) +#define SDA_OUTINIT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08) + +/* SCL is GPIOD.4 */ +#define SCL_INPUT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10) +#define SCL_OUTPUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10) +#define SCL_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10) +#define SCL_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10) +#define SCL (GPIOD_OUTPUT_EN & 0x10) + +/* arbitrary delay loop */ +#define DELAY udelay(10) + +static void fmradio_i2c_start(void) +{ + SCL_HI; + SCL_OUTPUT; + SDA_HI_IN; + SDA_OUTINIT; + DELAY; + SDA_LO_OUT; + DELAY; + SCL_LO; +} + +static void fmradio_i2c_stop(void) +{ + SDA_LO_OUT; + DELAY; + SCL_HI; + DELAY; + SDA_HI_IN; +} + +/* Generate ACK or NACK */ +static void fmradio_i2c_ack(bool nack) +{ + /* Here's the deal. The slave is slow, and sometimes needs to wait + before it can receive the acknowledge. Therefore it forces the clock + low until it is ready. We need to poll the clock line until it goes + high before we release the ack. + + In their infinite wisdom, iriver didn't pull up the SCL line, so + we have to drive the SCL high repeatedly to simulate a pullup. */ + + if (nack) + { + SDA_HI_IN; + } + else + { + SDA_LO_OUT; + } + DELAY; + + SCL_HI; +#if 0 + do + { + SCL_OUTPUT; /* Set the clock to output */ + SCL_INPUT; /* Set the clock to input */ + DELAY; + } + while(!SCL); /* and wait for the slave to release it */ +#endif + SCL_OUTPUT; + SCL_LO; +} + +static int fmradio_i2c_getack(void) +{ + int ret = 1; + + /* Here's the deal. The slave is slow, and sometimes needs to wait + before it can send the acknowledge. Therefore it forces the clock + low until it is ready. We need to poll the clock line until it goes + high before we read the ack. + + In their infinite wisdom, iriver didn't pull up the SCL line, so + we have to drive the SCL high repeatedly to simulate a pullup. */ + + SDA_HI_IN; + DELAY; + + SCL_HI; /* set clock to high */ +#if 0 + do + { + SCL_OUTPUT; /* Set the clock to output */ + SCL_INPUT; /* Set the clock to input */ + DELAY; + } + while(!SCL); /* and wait for the slave to release it */ +#endif + if (SDA) + ret = 0; /* ack failed */ + + SCL_OUTPUT; + SCL_LO; + + return ret; +} + +static void fmradio_i2c_outb(unsigned char byte) +{ + int i; + + /* clock out each bit, MSB first */ + for ( i=0x80; i; i>>=1 ) { + if ( i & byte ) + { + SDA_HI_IN; + } + else + { + SDA_LO_OUT; + } + DELAY; + SCL_HI; + DELAY; + SCL_LO; + } +} + +static unsigned char fmradio_i2c_inb(void) +{ + int i; + unsigned char byte = 0; + + SDA_HI_IN; + /* clock in each bit, MSB first */ + for ( i=0x80; i; i>>=1 ) { + DELAY; + SCL_HI; + DELAY; + if ( SDA ) + byte |= i; + SCL_LO; + } + + return byte; +} + +int fmradio_i2c_write(int address, const unsigned char* buf, int count) +{ + int i,x=0; + + fmradio_i2c_start(); + fmradio_i2c_outb(address & 0xfe); + if (fmradio_i2c_getack()) + { + for (i=0; i0; i--) + { + *buf++ = fmradio_i2c_inb(); + fmradio_i2c_ack(i == 1); + } + } + else + x=-1; + fmradio_i2c_stop(); + return x; +} + + +#else /* IRIVER_H10 */ + +/* cute little functions, atomic read-modify-write */ #define SDA_LO and_b(~0x10, &PBDRL) #define SDA_HI or_b(0x10, &PBDRL) #define SDA_INPUT and_b(~0x10, &PBIORL) @@ -428,6 +634,6 @@ fmradio_i2c_stop(); return x; } - +#endif /* IRIVER_H10 */ #endif #endif