1.1 --- a/pkg/devices/lib/i2c/src/jz4780.cc Sun Jul 21 22:23:06 2019 +0200
1.2 +++ b/pkg/devices/lib/i2c/src/jz4780.cc Mon Jul 22 00:17:30 2019 +0200
1.3 @@ -422,6 +422,36 @@
1.4 return _regs[Int_status] & Int_tx_abort;
1.5 }
1.6
1.7 +int
1.8 +I2c_jz4780_channel::read_done()
1.9 +{
1.10 + return _pos == _total;
1.11 +}
1.12 +
1.13 +int
1.14 +I2c_jz4780_channel::write_done()
1.15 +{
1.16 + return _reqpos == _total;
1.17 +}
1.18 +
1.19 +unsigned
1.20 +I2c_jz4780_channel::have_read()
1.21 +{
1.22 + return _pos;
1.23 +}
1.24 +
1.25 +unsigned
1.26 +I2c_jz4780_channel::have_written()
1.27 +{
1.28 + return _reqpos;
1.29 +}
1.30 +
1.31 +int
1.32 +I2c_jz4780_channel::failed()
1.33 +{
1.34 + return _fail;
1.35 +}
1.36 +
1.37
1.38
1.39 // Send read commands for empty queue entries.
1.40 @@ -447,12 +477,12 @@
1.41
1.42 // Queue read requests for any remaining queue entries.
1.43
1.44 - for (unsigned int i = 0; i < can_queue; i++)
1.45 + while (can_queue && can_send())
1.46 + {
1.47 _regs[Smb_data_command] = Smb_command_read;
1.48 -
1.49 - // Track queued messages and requested positions.
1.50 -
1.51 - _reqpos += can_queue;
1.52 + _reqpos++;
1.53 + can_queue--;
1.54 + }
1.55
1.56 // Issue the stop condition after the final read request.
1.57 // In practice, an extra read request works better since it does not risk a
1.58 @@ -461,19 +491,30 @@
1.59 if (_total == _reqpos)
1.60 _regs[Smb_data_command] = Smb_command_read;
1.61 //stop();
1.62 +
1.63 + // Update the threshold to be notified of any reduced remaining amount.
1.64 +
1.65 + set_read_threshold();
1.66 }
1.67
1.68 // Send write commands for empty queue entries.
1.69
1.70 void
1.71 -I2c_jz4780_channel::queue_writes(uint8_t buf[], unsigned int *pos, unsigned int total)
1.72 +I2c_jz4780_channel::queue_writes()
1.73 {
1.74 + unsigned int remaining = _total - _reqpos;
1.75 + unsigned int can_queue = Smb_fifo_limit;
1.76 +
1.77 + if (remaining < can_queue)
1.78 + can_queue = remaining;
1.79 +
1.80 // Queue write requests for any remaining queue entries.
1.81
1.82 - while ((*pos < total) && can_send() && !write_failed())
1.83 + while (can_queue && can_send())
1.84 {
1.85 - _regs[Smb_data_command] = Smb_command_write | buf[*pos];
1.86 - (*pos)++;
1.87 + _regs[Smb_data_command] = Smb_command_write | _buf[_reqpos];
1.88 + _reqpos++;
1.89 + can_queue--;
1.90 }
1.91 }
1.92
1.93 @@ -482,36 +523,27 @@
1.94 void
1.95 I2c_jz4780_channel::store_reads()
1.96 {
1.97 - int have_read = 0;
1.98 -
1.99 // Read any input and store it in the buffer.
1.100
1.101 - while (have_input() && (_pos < _total))
1.102 + while (have_input() && (_pos < _reqpos))
1.103 {
1.104 _buf[_pos] = _regs[Smb_data_command] & 0xff;
1.105 _pos++;
1.106 -
1.107 - have_read = 1;
1.108 }
1.109 -
1.110 - // Update the threshold to be notified of any reduced remaining amount.
1.111 -
1.112 - if (have_read)
1.113 - set_read_threshold();
1.114 }
1.115
1.116 void
1.117 I2c_jz4780_channel::set_read_threshold()
1.118 {
1.119 - unsigned int remaining = _total - _pos;
1.120 + unsigned int queued = _reqpos - _pos;
1.121
1.122 - if (!remaining)
1.123 + if (!queued)
1.124 return;
1.125
1.126 - // Read all remaining.
1.127 + // Read all expected.
1.128
1.129 - if (remaining <= Smb_fifo_limit)
1.130 - _regs[Rx_fifo_thold] = remaining - 1;
1.131 + if (queued <= Smb_fifo_limit)
1.132 + _regs[Rx_fifo_thold] = queued - 1;
1.133
1.134 // Read to limit.
1.135
1.136 @@ -538,53 +570,38 @@
1.137 {
1.138 if (read_failed() || write_failed())
1.139 {
1.140 -#if 0
1.141 - printf("intst*=%x\n", (uint32_t) _regs[Int_status]);
1.142 - printf("rxfifo=%d\n", (uint32_t) _regs[Rx_fifo_count] & 0x3f);
1.143 - printf("smbabtsrc=%x\n", (uint32_t) _regs[Trans_abort_status0]);
1.144 -#endif
1.145 _fail = 1;
1.146 return;
1.147 }
1.148
1.149 - if (_pos < _total)
1.150 - {
1.151 - if (_regs[Int_status] & Int_rx_full)
1.152 - store_reads();
1.153 - if (_regs[Int_status] & Int_tx_empty)
1.154 - queue_reads();
1.155 - }
1.156 -}
1.157 -
1.158 -int
1.159 -I2c_jz4780_channel::read_done()
1.160 -{
1.161 - return _pos == _total;
1.162 -}
1.163 -
1.164 -unsigned
1.165 -I2c_jz4780_channel::have_read()
1.166 -{
1.167 - return _pos;
1.168 -}
1.169 -
1.170 -int
1.171 -I2c_jz4780_channel::read_incomplete()
1.172 -{
1.173 - return _fail;
1.174 + if (_regs[Int_status] & Int_rx_full)
1.175 + store_reads();
1.176 + if (_regs[Int_status] & Int_tx_empty)
1.177 + queue_reads();
1.178 }
1.179
1.180 // Write to the target device.
1.181
1.182 void
1.183 -I2c_jz4780_channel::write(uint8_t buf[], unsigned int total)
1.184 +I2c_jz4780_channel::start_write(uint8_t buf[], unsigned int total)
1.185 {
1.186 - unsigned int pos = 0;
1.187 + _buf = buf;
1.188 + _total = total;
1.189 + _reqpos = 0;
1.190 + _fail = 0;
1.191 +}
1.192
1.193 - while ((pos < total) && !write_failed())
1.194 +void
1.195 +I2c_jz4780_channel::write()
1.196 +{
1.197 + if (write_failed())
1.198 {
1.199 - queue_writes(buf, &pos, total);
1.200 + _fail = 1;
1.201 + return;
1.202 }
1.203 +
1.204 + if (_regs[Int_status] & Int_tx_empty)
1.205 + queue_writes();
1.206 }
1.207
1.208 // Explicitly stop communication.
1.209 @@ -656,24 +673,39 @@
1.210 static_cast<I2c_jz4780_channel *>(i2c_channel)->read();
1.211 }
1.212
1.213 +void jz4780_i2c_start_write(void *i2c_channel, uint8_t buf[], unsigned int total)
1.214 +{
1.215 + static_cast<I2c_jz4780_channel *>(i2c_channel)->start_write(buf, total);
1.216 +}
1.217 +
1.218 +void jz4780_i2c_write(void *i2c_channel)
1.219 +{
1.220 + static_cast<I2c_jz4780_channel *>(i2c_channel)->write();
1.221 +}
1.222 +
1.223 int jz4780_i2c_read_done(void *i2c_channel)
1.224 {
1.225 return static_cast<I2c_jz4780_channel *>(i2c_channel)->read_done();
1.226 }
1.227
1.228 +int jz4780_i2c_write_done(void *i2c_channel)
1.229 +{
1.230 + return static_cast<I2c_jz4780_channel *>(i2c_channel)->write_done();
1.231 +}
1.232 +
1.233 unsigned int jz4780_i2c_have_read(void *i2c_channel)
1.234 {
1.235 return static_cast<I2c_jz4780_channel *>(i2c_channel)->have_read();
1.236 }
1.237
1.238 -int jz4780_i2c_read_incomplete(void *i2c_channel)
1.239 +unsigned int jz4780_i2c_have_written(void *i2c_channel)
1.240 {
1.241 - return static_cast<I2c_jz4780_channel *>(i2c_channel)->read_incomplete();
1.242 + return static_cast<I2c_jz4780_channel *>(i2c_channel)->have_written();
1.243 }
1.244
1.245 -void jz4780_i2c_write(void *i2c_channel, uint8_t buf[], unsigned int total)
1.246 +int jz4780_i2c_failed(void *i2c_channel)
1.247 {
1.248 - static_cast<I2c_jz4780_channel *>(i2c_channel)->write(buf, total);
1.249 + return static_cast<I2c_jz4780_channel *>(i2c_channel)->failed();
1.250 }
1.251
1.252 void jz4780_i2c_stop(void *i2c_channel)