<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jun 19, 2015 at 6:43 PM, Gary Buhrmaster <span dir="ltr"><<a href="mailto:gary.buhrmaster@gmail.com" target="_blank">gary.buhrmaster@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Fri, Jun 19, 2015 at 10:24 PM, Joseph Fry <<a href="mailto:joe@thefrys.com">joe@thefrys.com</a>> wrote:<br>
....<br>
</span><span class="">> I am on an IPTV system<br>
<br>
</span>Ah, yes, the IPTV providers do not have to play by the<br>
same regulations that the cable companies have to<br>
(the FCC is going to be changing that, but the studies<br>
are ongoing to provide recommendations for the next<br>
generation technologies and requirements, with the<br>
results of the study due in the fall(*)).<br>
<br>
Gary<br>
<br>
<br>
(*) With an anticipated outcry by some of "It is the<br>
end of the CableCARD as we know it, and the sky<br>
is falling".</blockquote><div><br></div><div>So, I spent the morning looking at the code for lirc_zilog and I think I found the problem block of code:</div><div><br></div><div><font face="monospace, monospace"> <span class="" style="white-space:pre"> </span>/* Send the data block */</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>ret = send_data_block(tx, data_block);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>if (ret != 0)</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>return ret;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>/* Send data block length? */</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>buf[0] = 0x00;</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>buf[1] = 0x40;</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>ret = i2c_master_send(tx->c, buf, 2);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>if (ret != 2) {</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>return ret < 0 ? ret : -EFAULT;</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>/* Give the z8 a moment to process data block */</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>for (i = 0; i < 10; i++) {</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>ret = i2c_master_send(tx->c, buf, 1);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>if (ret == 1)</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>break;</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>udelay(100);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>}</font></div><div><br></div><div>From what I can tell, it sends a block of data, then sends it's length... and finally it loops for 1 second in 100ms increments waiting for i2c to say it completed processing (return 1). My guess is that i2c isn't returning a 1, and this loop continues for the entire 1 second before the process continues on.</div><div><br></div><div>A quick look at the code for i2c_master_send suggests I am right:</div><div><br></div><div><div><font face="monospace, monospace">/**</font></div><div><font face="monospace, monospace">2045 * i2c_master_send - issue a single I2C message in master transmit mode</font></div><div><font face="monospace, monospace">2046 * @client: Handle to slave device</font></div><div><font face="monospace, monospace">2047 * @buf: Data that will be written to the slave</font></div><div><font face="monospace, monospace">2048 * @count: How many bytes to write, must be less than 64k since msg.len is u16</font></div><div><font face="monospace, monospace">2049 *</font></div><div><font face="monospace, monospace">2050 * Returns negative errno, or else the number of bytes written.</font></div><div><font face="monospace, monospace">2051 */</font></div><div><font face="monospace, monospace">2052 int i2c_master_send(const struct i2c_client *client, const char *buf, int count)</font></div><div><font face="monospace, monospace">2053 {</font></div><div><font face="monospace, monospace">2054 int ret;</font></div><div><font face="monospace, monospace">2055 struct i2c_adapter *adap = client->adapter;</font></div><div><font face="monospace, monospace">2056 struct i2c_msg msg;</font></div><div><font face="monospace, monospace">2057 </font></div><div><font face="monospace, monospace">2058 msg.addr = client->addr;</font></div><div><font face="monospace, monospace">2059 msg.flags = client->flags & I2C_M_TEN;</font></div><div><font face="monospace, monospace">2060 msg.len = count;</font></div><div><font face="monospace, monospace">2061 msg.buf = (char *)buf;</font></div><div><font face="monospace, monospace">2062 </font></div><div><font face="monospace, monospace">2063 ret = i2c_transfer(adap, &msg, 1);</font></div><div><font face="monospace, monospace">2064 </font></div><div><font face="monospace, monospace">2065 /*</font></div><div><font face="monospace, monospace">2066 * If everything went ok (i.e. 1 msg transmitted), return #bytes</font></div><div><font face="monospace, monospace">2067 * transmitted, else error code.</font></div><div><font face="monospace, monospace">2068 */</font></div><div><font face="monospace, monospace">2069 return (ret == 1) ? count : ret;</font></div><div><font face="monospace, monospace">2070 }<br><br>In the function description you see that it says it returns a negative error number, or the number of bytes written. If you look at the actual return statement, it's returning the count (or the error from i2c_transfer).</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I think I need to patch lirc_zilog:</font></div><div><font face="monospace, monospace"><br></font></div><div><div><span style="font-family:monospace,monospace;white-space:pre"> </span><font face="monospace, monospace">for (i = 0; i < 10; i++) {</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>ret = i2c_master_send(tx->c, buf, 1);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre">- </span>if (ret == 1)</font></div><div><span class="" style="font-family:monospace,monospace;white-space:pre">+ </span><span style="font-family:monospace,monospace">if (ret > 0)</span><br></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>break;</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>udelay(100);</font></div><div><font face="monospace, monospace"><span class="" style="white-space:pre"> </span>}</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Can anyone confirm my conclusion? My programming skills are limited to scripts... so this is new territory for me.</font></div></div></div></div>