diff --git a/firmware/drivers/tuner/rda5802.c b/firmware/drivers/tuner/rda5802.c index 377bdd1e6f..3f122714bd 100644 --- a/firmware/drivers/tuner/rda5802.c +++ b/firmware/drivers/tuner/rda5802.c @@ -42,6 +42,7 @@ #define RSSI_MAX 70 /** Registers and bits **/ +#define CHIPID 0x0 #define POWERCFG 0x2 #define CHANNEL 0x3 #define SYSCONFIG1 0x4 @@ -52,7 +53,6 @@ #define SYSCONFIG6 0x9 /* undocumented */ #define READCHAN 0xA #define STATUSRSSI 0xB -#define IDENT 0xC /* POWERCFG (0x2) */ @@ -190,7 +190,21 @@ static void rda5802_sleep(int snooze) bool rda5802_detect(void) { - return ((rda5802_read_reg(IDENT) & 0xFF00) == 0x5800); + /* The RDA5802 has a weird wrap-around at 0x40. Upon initialisation, it will copy the Chip ID + * to register 0xC but since this register is also used for RDS, we cannot rely on its content + * until we softreset. But we cannot soft-reset until we confirm the tuner type... So we really + * need to register 0, which means reading 0x40 registers. + * NOTE: the datasheet says that it wraps around at 0x3A but this is wrong. */ + + /* we want to read registers 0x00/0x01, aka 0x40/0x41 because of wrapping, tuner starts reading + * at 0xA so we need to read 0x40 - 0xA + 2 registers, each register is two bytes. Thats + * (0x40 - 0xA + 2) * 2 = 0x6e bytes */ + unsigned char buf[0x70]; + fmradio_i2c_read(I2C_ADR, buf, sizeof(buf)); + cache[CHIPID] = buf[0x6c] << 8 | buf[0x6d]; + cache[1] = buf[0x6e] << 8 | buf[0x6f]; /* unknown register, maybe firmware ID or related */ + + return ((cache[CHIPID] & 0xFF00) == 0x5800); } void rda5802_init(void)