diff options
Diffstat (limited to 'firmware/target/hosted')
-rw-r--r-- | firmware/target/hosted/sonynwz/nwz_tuner.h | 19 | ||||
-rw-r--r-- | firmware/target/hosted/sonynwz/radio-nwz.c | 15 |
2 files changed, 30 insertions, 4 deletions
diff --git a/firmware/target/hosted/sonynwz/nwz_tuner.h b/firmware/target/hosted/sonynwz/nwz_tuner.h index 36b1b9634c..03aa8dac74 100644 --- a/firmware/target/hosted/sonynwz/nwz_tuner.h +++ b/firmware/target/hosted/sonynwz/nwz_tuner.h @@ -25,11 +25,24 @@ /* we only describe the private ioctl, the rest is standard v4l2 */ #define NWZ_TUNER_TYPE 'v' +/* Of course Sony had to change something in the structure without changing the ioctl codes. + * Fortunately they are close enough so that some clever naming and ifdef solves the problem. */ + +#if defined(SONY_NWZE350) || defined(SONY_NWZE450) || defined(SONY_NWZE460) || \ + defined(SONY_NWZA860) || defined(SONY_NWZS750) +#define NWZ_TUNER_V1 +#endif + +#ifdef NWZ_TUNER_V1 + +#define NWZ_TUNER_REG_COUNT 14 + +#else /* !NWZ_TUNER_V1 */ + #define NWZ_TUNER_REG_COUNT 20 -/* there is something slightly fishy about this structure, the ioctl code says it must be of size - * 0x2C but the disassembled code looks like it uses a size of 0x24, probably Sony's code is - * massively broken */ +#endif /* NWZ_TUNER_V1 */ + struct nwz_tuner_ioctl_t { union diff --git a/firmware/target/hosted/sonynwz/radio-nwz.c b/firmware/target/hosted/sonynwz/radio-nwz.c index db4ffda465..3cbc8eb551 100644 --- a/firmware/target/hosted/sonynwz/radio-nwz.c +++ b/firmware/target/hosted/sonynwz/radio-nwz.c @@ -91,7 +91,10 @@ int fmradio_i2c_write(unsigned char address, unsigned char* buf, int count) req.put.val = REG_SWAP(*(REG_TYPE *)&buf[i * REG_SIZE]); int ret = ioctl(radio_fd, NWZ_TUNER_PUT_REG, &req); if(ret != 0) + { + perror("tuner put_reg error"); return ret; + } } return 0; } @@ -103,8 +106,18 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) memset(&req, 0, sizeof(req)); // just to avoid garbage in int ret = ioctl(radio_fd, NWZ_TUNER_GET_REG_ALL, &req); if(ret != 0) + { + perror("radio get_reg_all error"); return ret; + } for(int i = 0; i < count / REG_SIZE; i++) - *(REG_TYPE *)&buf[i * REG_SIZE] = REG_SWAP(req.regs[(READ_START_REG + i) % REG_COUNT]); + { + /* on version 1, some registers are not reported by Sony's driver */ + int sony_reg = (READ_START_REG + i) % REG_COUNT; + if(sony_reg < NWZ_TUNER_REG_COUNT) + *(REG_TYPE *)&buf[i * REG_SIZE] = REG_SWAP(req.regs[sony_reg]); + else + *(REG_TYPE *)&buf[i * REG_SIZE] = 0xfeca; /* recognizable pattern for debug menu */ + } return 0; } |