summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-11-14 00:24:42 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-11-14 00:27:28 +0100
commitbd8dd62db7bd55a465c745dfda30964d4d582f71 (patch)
tree91ae15b25995792f00d642138c3e68e11681f9f9
parent7272f821da49020dc8a3e2f865f0fee82e8f4bf9 (diff)
downloadrockbox-bd8dd62db7bd55a465c745dfda30964d4d582f71.tar.gz
rockbox-bd8dd62db7bd55a465c745dfda30964d4d582f71.zip
nwz: fix tuner on older players (also fixes audio because Sony)
Change-Id: I1915bcfc27708d34a9dde81fce1e0bc0b01e1040
-rw-r--r--firmware/target/hosted/sonynwz/nwz_tuner.h19
-rw-r--r--firmware/target/hosted/sonynwz/radio-nwz.c15
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 @@
25/* we only describe the private ioctl, the rest is standard v4l2 */ 25/* we only describe the private ioctl, the rest is standard v4l2 */
26#define NWZ_TUNER_TYPE 'v' 26#define NWZ_TUNER_TYPE 'v'
27 27
28/* Of course Sony had to change something in the structure without changing the ioctl codes.
29 * Fortunately they are close enough so that some clever naming and ifdef solves the problem. */
30
31#if defined(SONY_NWZE350) || defined(SONY_NWZE450) || defined(SONY_NWZE460) || \
32 defined(SONY_NWZA860) || defined(SONY_NWZS750)
33#define NWZ_TUNER_V1
34#endif
35
36#ifdef NWZ_TUNER_V1
37
38#define NWZ_TUNER_REG_COUNT 14
39
40#else /* !NWZ_TUNER_V1 */
41
28#define NWZ_TUNER_REG_COUNT 20 42#define NWZ_TUNER_REG_COUNT 20
29 43
30/* there is something slightly fishy about this structure, the ioctl code says it must be of size 44#endif /* NWZ_TUNER_V1 */
31 * 0x2C but the disassembled code looks like it uses a size of 0x24, probably Sony's code is 45
32 * massively broken */
33struct nwz_tuner_ioctl_t 46struct nwz_tuner_ioctl_t
34{ 47{
35 union 48 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)
91 req.put.val = REG_SWAP(*(REG_TYPE *)&buf[i * REG_SIZE]); 91 req.put.val = REG_SWAP(*(REG_TYPE *)&buf[i * REG_SIZE]);
92 int ret = ioctl(radio_fd, NWZ_TUNER_PUT_REG, &req); 92 int ret = ioctl(radio_fd, NWZ_TUNER_PUT_REG, &req);
93 if(ret != 0) 93 if(ret != 0)
94 {
95 perror("tuner put_reg error");
94 return ret; 96 return ret;
97 }
95 } 98 }
96 return 0; 99 return 0;
97} 100}
@@ -103,8 +106,18 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
103 memset(&req, 0, sizeof(req)); // just to avoid garbage in 106 memset(&req, 0, sizeof(req)); // just to avoid garbage in
104 int ret = ioctl(radio_fd, NWZ_TUNER_GET_REG_ALL, &req); 107 int ret = ioctl(radio_fd, NWZ_TUNER_GET_REG_ALL, &req);
105 if(ret != 0) 108 if(ret != 0)
109 {
110 perror("radio get_reg_all error");
106 return ret; 111 return ret;
112 }
107 for(int i = 0; i < count / REG_SIZE; i++) 113 for(int i = 0; i < count / REG_SIZE; i++)
108 *(REG_TYPE *)&buf[i * REG_SIZE] = REG_SWAP(req.regs[(READ_START_REG + i) % REG_COUNT]); 114 {
115 /* on version 1, some registers are not reported by Sony's driver */
116 int sony_reg = (READ_START_REG + i) % REG_COUNT;
117 if(sony_reg < NWZ_TUNER_REG_COUNT)
118 *(REG_TYPE *)&buf[i * REG_SIZE] = REG_SWAP(req.regs[sony_reg]);
119 else
120 *(REG_TYPE *)&buf[i * REG_SIZE] = 0xfeca; /* recognizable pattern for debug menu */
121 }
109 return 0; 122 return 0;
110} 123}