Nvec
Toshiba's kernel
nvec_i2c_transport.c - "Work around for AP20 New Slave Hw Bug. Give 1us extra."
Workaround for AP20 New I2C Slave Controller bug #626607
NVEC_CMD_SLEEP_APRECOVERY in Folio's kernel
Discussions
Small nvec discussion log:
<stuw> marvin24, srwarren I have a question about nvec implementation. http://gitorious.org/~marvin24/ac100/marvin24s-kernel/blobs/rel-15r7-ac100/drivers/staging/nvec/nvec.c#line324 <- in case of error we keep msg allocated. After few errors we have no available slots in msg_pool. I suppose msg is not needed any more if error has occurred. Did I miss something in my reasoning? <marvin24> stuw: I already send a fix for rpiloose for this <marvin24> for->from <marvin24> ah,maybe not - this is a different one <marvin24> stuw: isn't the message freed in line 337? <marvin24> ah, no, err == 0 is the error condition <marvin24> weird <stuw> marvin24, code looks like we want to wait/get responce at any price <marvin24> stuw: in the error case the message pointer is just reset <marvin24> no new buffer will get reserved <marvin24> it just picks the old one from the list <stuw> marvin24> stuw: in the error case the message pointer is just reset <- are you talking about msg->pos = 0 ? <stuw> nvec_msg_alloc returns first unused (used flag is 0) msg from pool. nvec_request_master never marks msg as unused (never call nvec_msg_free for this msg) in case of error. <stuw> I didn't analyze nvec driver enough to understand what msg->pos = 0 means :( <marvin24> stuw: request_master checks if there is a message queued to be send to the ec <marvin24> the queue is a list named tx_data <marvin24> if the list is not empty, it will notify the ec to start the transfer (we can't do it because we are slave) <marvin24> if after 5 secs the transfer is not finished, it will reset the message pointer (pointing to the next char to send) <marvin24> the buffer is only freed if the message was transfered successfully <marvin24> but if we timeout too often, we cannot accept new messages anymore <marvin24> the problem is that most messages are async and they don't care about return values <marvin24> if the tx queue is full (because we timeout all the time), we cannot send anymore <marvin24> in fact, (nearly) all communication should be sync I think <marvin24> but the sync write is not very robust yet <marvin24> and still needs a lot of work <stuw> marvin24, thanks for explanation. <marvin24> stuw: thanks for review ! <stuw> marvin24, is nvec_request_master (i.e. send to EC) and nvec_dispatch (i.e. read from EC) performed in parallel ? I mean we should read all messages from EC before send anything if send to EC will block read from EC operation (If I understood EC documentation correctly) <marvin24> stuw: no, they can be on the fly (in theroy) <marvin24> but it's possible that we are not sending a new message unless the old one is finished <marvin24> the sending, not the receive of the ack message <stuw> Prev msg is a little bit wrong: we should read responses before send requests. <stuw> marvin24, ok. thx once again :) <marvin24> stuw: feel free to create a hack which improves it <stuw> marvin24, I should understand code first :) ... <rpiloose> dump of the code by muromec @ 17 march 2011: http://crap.muromec.org.ua/ac100/ecdump.bin <rpiloose> of shit, I missed that: http://share.grandou.net/ac100/ec/
Errors
- nvec nvec.2: timeout waiting for ec transfer
We set gpio to initiate transfer but failed to transfer packet to EC for some reason.
- nvec nvec.2: could not allocate RX buffer
Receive pool is full. Looks like rx messages keep used (not freed).
- nvec nvec.2: unexpected status flags 0x18 during state 1
- nvec nvec.2: unexpected status flags 0x08 during state 0
- nvec nvec.2: unexpected status flags 0x1c during state 0
- nvec nvec.2: unexpected status flags 0x18 during state 0
Have no idea yet. 0x08 = 01000b (bits: 3) 0x18 = 11000b (bits: 3,4) 0x1c = 11100b (bits: 2,3,4)
<6>[ 113.168691] psmouse.c: Wheel Mouse at nvec/input0 lost synchronization, throwing 2 bytes away. <6>[ 113.705433] psmouse.c: resync failed, issuing reconnect request <6>[ 115.309056] elantech: assuming hardware version 3 (with firmware version 0x150500) <6>[ 115.357593] elantech: Synaptics capabilities query result 0x69, 0x17, 0x09. <6>[ 115.569173] input: ETPS/2 Elantech Touchpad as /devices/serio0/input/input7
Have no idea yet.
Logs
20-th of September 2014 - dmesg from marvin24
Debugging
Hardware:
Software:
OpenBench Logic Sniffer 3.08 (home page)
Notes
Driver must be Communications port (COM and LPT section in device manager)
Sometimes I2C analyzer detects false START event in the middle of transaction if 1MHz is used to capture. 2MHz helps with the issue.
Results
Case 1 - Android 2.1 sound playback (volume tuning)
EC request line
Mute line
Case 2 - sos-uboot with 3.17-rc4 and NVEC (without ack delays) on top of tegra-i2c slave
Issue: huge delay between first and second bytes
i2cdetect
i2cdetect doesn't find anything on the i2c bus. But using logic analyzer I fugured out that scan is actually happens. TODO: add logs
NVEC serial port (uart)
15:23 < stuw__> marvin24, hi. I got uart data from nvec - http://pastebin.com/BnQkpQ6k 15:24 < stuw__> I failed to solder a wire to nvec leg to sniff i2c :(( 16:50 < marvin24> stuw__: cool 16:50 < marvin24> but what does it mean? 16:55 < stuw__> marvin24, maybe some coded messages/statuses for debugging 16:57 < marvin24> is this during power on? 16:57 < stuw__> I'd like to sniff i2c bus on nvec and alc5632 + amp power rail 16:57 < stuw__> marvin24, it's power on (android boot) + few codes from poweroff by power button 16:59 < marvin24> ok
`�t8a��PMUSD N0N1@REQ=1 N2N3o01,F0,F0,o01,F0,40,o01,F0,41,o01,F0,42,o01,F0,43,o01,F0,44,o01,F0,45,o01,F0,46,o01,F0, 47,o01,F0,48,o01,F0,49,o01,F0,4A,o01,F0,4B,o01,F0,4C,o01,F0,4D,o01,F0,4E,o01,F0,4F,o01,F0,5 0,o01,F0,51,o01,F0,52,o01,F0,53,o01,F0,54,o01,F0,55,o01,F0,56,o01,F0,57,o01,F0,58,o01,F0,59 ,o01,F0,5A,o01,F0,5B,o01,F0,5C,o01,F0,5D,o01,F0,5E,o01,F0,5F,o01,F0,20,o01,F0,21,o01,F0,22, o01,F0,23,o01,F0,24,o01,F0,25,o01,F0,26,o01,F0,27,o01,F0,28,o01,F0,29,o01,F0,2A,o01,F0,2B,o 01,F0,2C,o01,F0,2D,o01,F0,60,o01,F0,61,o01,F0,62,o01,F0,63,o01,F0,64,o01,F0,65,o01,F0,66,o0 1,F0,67,o01,F0,68,o01,F0,69,o01,F0,80,o01,F0,81,o01,F0,82,o01,F0,83,o01,F0,84,o01,F0,85,o01 ,F0,86,o01,F0,87,o01,F0,88,o01,F0,89,o01,F0,8A,o01,F0,8B,o01,F0,8C,o01,F0,8D,o01,F0,8E,o01, F0,8F,o01,F0,90,o01,F0,91,o01,F0,92,o01,F0,93,o01,F0,94,o01,F0,95,o01,F0,96,o01,F0,97,o01,F 0,98,o01,F0,99,o01,F0,9A,o01,F0,9B,o01,F0,9C,o01,F0,9D,SD13,F0,F1
void FUN_CODE_e1e3(byte param_1) { char cVar1; DAT_EXTMEM_f5d3 = param_1 >> 4; DAT_EXTMEM_f5d2 = param_1 & 0xf; if ((DAT_EXTMEM_f5d3 < 10) << 7 < '\0') { cVar1 = DAT_EXTMEM_f5d3 + 0x30; } else { cVar1 = DAT_EXTMEM_f5d3 + 0x37; } FUN_CODE_ebc8_serial_port_xfer1b(cVar1); if ((DAT_EXTMEM_f5d2 < 10) << 7 < '\0') { cVar1 = DAT_EXTMEM_f5d2 + 0x30; } else { cVar1 = DAT_EXTMEM_f5d2 + 0x37; } FUN_CODE_ebc8_serial_port_xfer1b(cVar1); FUN_CODE_ebc8_serial_port_xfer1b(0x2c); return; }