2 i2c-serial.c - I2C Driver for I2C on serial port
3 Copyright (c) 2007 Momtchil Momtchev <momtchil@momtchev.com>
4 Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* This interfaces to the I2C bus connected to a serial port */
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/pci.h>
29 #include <linux/types.h>
30 #include <linux/fcntl.h>
31 #include <linux/interrupt.h>
32 #include <linux/i2c.h>
33 #include <linux/i2c-algo-bit.h>
34 #include <linux/tty.h>
35 #include <linux/poll.h>
36 #include <linux/input.h>
37 #include <linux/serio.h>
39 #include <linux/errno.h>
40 #include <linux/proc_fs.h>
42 #define I2CSERIAL_DEBUG 0
44 #if I2CSERIAL_DEBUG==1
45 #define VERSION "1.15d"
47 #define VERSION "1.15"
50 #define I2CSERIAL_STATS
55 * v1.01 (and following) by Brice Marnier <marnier@aldebaran-robotics.com>
56 * adapted to match new PSoC protocol
57 * v1.03 - support for PSoC Watchdog reset
58 * v1.04 - speed enhancement
59 * v1.05 - i2c_transfer support, firmware version display at startup
60 * v1.06 - escape sequence bugfix
61 * v1.07 - added consistent error codes
63 * v1.08 - reduced logging in potentially repetitive error cases
64 * v1.10 - /proc/i2cstats version info and error statistics
65 * v1.11 - timeout = 52 (make the flasher work)
66 * v1.12 - send reset to the psoc in i2c mode too
67 * v1.13 - handle wakeup order from the psoc
68 * - cedric gestes <gestes@aldebaran-robotics.com>
69 * v1.14 - handle i2c_smbus_read_i2c_block_data
70 * - code factorisation
71 * - cedric gestes <gestes@aldebaran-robotics.com>
73 * todo (one day /sys/... equivalent ?)
76 #define DRV_NAME "Serial I2C/SMBus driver"
77 const char drv_name
[] = DRV_NAME
;
79 MODULE_AUTHOR("Momtchil Momtchev <momtchil@momtchev.com>, Brice Marnier <briareos@hecatonchires.com>");
80 MODULE_DESCRIPTION(DRV_NAME
);
81 MODULE_LICENSE("GPL");
82 MODULE_VERSION(VERSION
);
84 #define TIMEOUT msecs_to_jiffies(52)
85 //#define TIMEOUT_RESET msecs_to_jiffies(50)
86 #define I2C_SERIAL_BUFFER_LENGTH 256
88 #include "psoc-protocol.h"
91 #define I2C_STATE_IDLE 0x01
92 /* Sending on serial */
93 #define I2C_STATE_SEND 0x02
94 /* Waiting for reply, probably [Esc]*/
95 #define I2C_STATE_WAIT 0x04
96 /* Waiting for raw input data or [Esc]*/
97 #define I2C_STATE_READ 0x06
98 /* Waiting for input after ESCAPE_CHAR */
99 #define I2C_STATE_CMD 0x08
100 /* Waiting for watchdog reset, i.e. [Esc]'z' after ~8ms idle*/
101 /* WAIT_WATCHDOG is 0x10 + IDLE, to be detected as an idle mode */
102 #define I2C_STATE_WAIT_WATCHDOG 0x11
103 /* Version request running = waiting for constant length string reply */
104 #define I2C_STATE_VERSION 0x20
106 #define I2C_ERROR_NAK ( -EAGAIN) // "Ressource temporarily unavailable"
107 #define I2C_ERROR_ADDRNAK ( -ENXIO) // "No such device or address"
108 #define I2C_ERROR_BUSY ( -EBUSY) // "Device or resource busy"
109 #define I2C_ERROR_STALL ( -EIO) // "Input/output error"
110 #define I2C_ERROR_TIMEOUT (-ETIMEDOUT) // "Connection timed out"
111 #define I2C_ERROR_OVERBUFF (-EOVERFLOW) // "Value too large..."
112 #define I2C_ERROR_RESET (-ECANCELED) // "Operation canceled"
113 #define I2C_ERROR_MTF (-ENOMEDIUM)
115 static DECLARE_WAIT_QUEUE_HEAD(wq
);
119 * 2.6.22.9 hacked to support read with size diff than 32
120 * in newer kernel 2.6.23 or later
121 * the previous I2C_SMBUS_I2C_BLOCK_DATA has been renamed
122 * I2C_SMBUS_I2C_BLOCK_BROKEN
124 * but I dont want to make that change here
127 #define I2C_SMBUS_I2C_BLOCK_DATA_ALL_SIZE 8
133 * structure for I2C-serial data
136 struct i2c_adapter adapter
;
137 struct i2c_client
*client
;
141 unsigned char * irq_buffer
; /* can point either to buffer below, or to provided buffer for I2C transfers */
142 unsigned char buffer
[I2C_SERIAL_BUFFER_LENGTH
];
143 unsigned int pos
; /* position inside the buffer */
144 u8 reply_count
; /* number of replies to wait for before command completion */
145 // u8 addr; /* last used address (useless) */
148 #ifdef I2CSERIAL_STATS
149 struct i2cserial_stats__
{
150 char firmware_version
[8];
151 long int serio_access
;
158 # define STAT(x) {x;}
163 #define I2CS_ERR(fmt, arg...) printk(KERN_ERR "i2c_serial {%s}: " fmt "\n" , __FUNCTION__ , ## arg)
164 #define I2CS_INFO(fmt, arg...) printk(KERN_INFO "i2c_serial [%s]: " fmt "\n" , __FUNCTION__ , ## arg)
165 #if I2CSERIAL_DEBUG==1
166 #define I2CS_DEBUG(fmt, arg...) printk(KERN_DEBUG "i2c_serial (%s): " fmt "\n" , __FUNCTION__ , ## arg)
168 #define I2CS_DEBUG(fmt, arg...) while (0) {}
173 * internal function to handle i2c buffer
175 static inline char *serial_append_escaped_byte(unsigned char *p
, unsigned char c
)
177 if (c
== ESCAPE_CHAR
)
183 static unsigned char *serial_append_read(unsigned char *p
, unsigned char address
, unsigned char size
)
187 *p
++ = (unsigned char)(address
& 0x7f);
188 p
= serial_append_escaped_byte(p
, size
);
192 static unsigned char *serial_append_write(unsigned char *p
, unsigned char address
, unsigned char data
)
196 *p
++ = (unsigned char)(address
& 0x7f);
197 p
= serial_append_escaped_byte(p
, (unsigned char)(data
& 0xff));
201 static unsigned char *serial_append_write_block(unsigned char *p
,
202 unsigned char address
,
210 *p
++ = (unsigned char)(address
& 0x7f);
211 for(i
= 0; i
< size
; ++i
) {
212 p
= serial_append_escaped_byte(p
, data
[i
]);
217 static unsigned char *serial_append_footer(unsigned char *p
)
226 /* {{{ i2c_serial_get_version : ask PSoC for firmware version
228 static inline char* i2c_serial_get_version(struct i2c_adapter
*adapter
) {
230 struct serio
*serio
= adapter
->algo_data
;
231 struct i2c_data
*i2cd
= serio_get_drvdata(serio
);
234 for (i
=0; i
<8; ++i
) {
236 STAT(i2cserial_stats
.firmware_version
[i
] = 0);
238 i2cd
->irq_buffer
= &(i2cd
->buffer
[0]);
240 I2CS_DEBUG("Asking for PSoC firmware version...");
241 I2CS_DEBUG("serio_write(0x%02x)", (unsigned)ESCAPE_CHAR
);
243 STAT(i2cserial_stats
.serio_access
++;)
244 if (serio_write(serio
, ESCAPE_CHAR
) < 0) {
245 I2CS_ERR("serio_write(0x%02x) failed", (unsigned)ESCAPE_CHAR
);
246 STAT(i2cserial_stats
.serio_err
++);
249 I2CS_DEBUG("serio_write(0x%02x)", (unsigned)CMD_VERSION
);
250 STAT(i2cserial_stats
.serio_access
++);
251 if (serio_write(serio
, CMD_VERSION
) < 0) {
252 I2CS_ERR("serio_write(0x%02x) failed", (unsigned)CMD_VERSION
);
253 STAT(i2cserial_stats
.serio_err
++);
256 i2cd
->state
= I2C_STATE_WAIT
;
257 wait_event_interruptible_timeout(wq
, i2cd
->state
== I2C_STATE_IDLE
, TIMEOUT
);
259 STAT(strncpy(i2cserial_stats
.firmware_version
, i2cd
->buffer
, 7));
260 // no need to check : if things went wrong, buffer is empty anyway...
262 } // i2c_serial_get_version }}}
265 //{{{ i2c_serio_i2c_xfer
266 static s32
i2c_serio_i2c_xfer(struct i2c_adapter
*adapter
, struct i2c_msg messages
[], int num
) {
268 struct serio
*serio
;
269 struct i2c_data
*i2cd
;
271 unsigned char *p
, *q
;
276 printk(KERN_ERR
"i2c-serial (%s): NULL adapter !", __FUNCTION__
);
280 serio
= adapter
->algo_data
;
281 i2cd
= serio_get_drvdata(serio
);
282 I2CS_DEBUG("J:%ld - %d I2C msg", jiffies
, num
);
283 STAT(i2cserial_stats
.i2crq
++);
284 for (i
=0; i
<num
; ++i
) {
286 if (messages
[i
].len
> (I2C_SERIAL_BUFFER_LENGTH
-1) ) {
287 I2CS_ERR("Cannot handle requests more than %d bytes long (asked=%d) !", (I2C_SERIAL_BUFFER_LENGTH
-1), messages
[i
].len
);
288 ret
= -EMSGSIZE
; // Message too long
292 if ( ! (i2cd
->state
& I2C_STATE_IDLE
) )
293 wait_event_interruptible_timeout(wq
, (i2cd
->state
&I2C_STATE_IDLE
) == I2C_STATE_IDLE
, TIMEOUT
);
295 if ( (i2cd
->state
& I2C_STATE_IDLE
) != I2C_STATE_IDLE
) {
296 I2CS_ERR("PSoC jammed !"); /* TODO reset PSoC*/
297 i2cd
->state
= I2C_STATE_IDLE
;
300 i2cd
->jiffies
= jiffies
;
302 i2cd
->reply_count
= 1;
305 if (messages
[i
].flags
& I2C_M_RD
) {
306 p
= serial_append_read(p
, messages
[i
].addr
, messages
[i
].len
);
307 i2cd
->state
= I2C_STATE_READ
;
308 /* prepare irq_buffer */
309 i2cd
->irq_buffer
= messages
[i
].buf
;
312 p
= serial_append_write_block(p
, messages
[i
].addr
, messages
[i
].buf
, messages
[i
].len
);
313 p
= serial_append_footer(p
);
314 i2cd
->state
= I2C_STATE_WAIT
;
317 /* send command via serio */
319 for (q
=i2cd
->buffer
; q
<p
; q
++) {
320 STAT(i2cserial_stats
.serio_access
++);
321 tmp
+=ret
=serio_write(serio
, *q
);
323 STAT(i2cserial_stats
.serio_err
++);
327 I2CS_DEBUG("serio_write() errors (%d)", -tmp
);
331 // wait for interrupt return
332 wait_event_interruptible_timeout(wq
, (i2cd
->state
& I2C_STATE_IDLE
) == I2C_STATE_IDLE
, TIMEOUT
);
334 if (! (i2cd
->state
& I2C_STATE_IDLE
) ) {
335 // I2CS_INFO("Interrupt timed out...");
336 #if I2CSERIAL_DEBUG==1
339 idx
=sprintf(&tmp_str
[0],"{");
340 for(q
=i2cd
->buffer
; q
<p
; ++q
) {
341 idx
+=sprintf(&tmp_str
[idx
],"%02x,", *q
);
343 idx
+=sprintf(&tmp_str
[idx
],"}");
345 I2CS_DEBUG("J:%d+%u time out sending buffer[]=%s", i2cd
->jiffies
, (unsigned)(jiffies
- i2cd
->jiffies
), tmp_str
);
347 i2cd
->state
= I2C_STATE_WAIT_WATCHDOG
;
348 // I2CS_DEBUG("serio_write(0x%02x)", (unsigned)ESCAPE_CHAR);
349 #ifdef I2CSERIAL_STATS
350 STAT(i2cserial_stats
.serio_access
++);
352 ret
=serio_write(serio
, ESCAPE_CHAR
);
354 STAT(i2cserial_stats
.serio_err
++);
356 STAT(i2cserial_stats
.serio_access
++);
357 ret
=serio_write(serio
, CMD_RESET
);
359 STAT(i2cserial_stats
.serio_err
++);
361 wait_event_interruptible_timeout(wq
, i2cd
->state
== I2C_STATE_IDLE
, TIMEOUT
);
362 ret
=-ETIME
; // "Timer expired"
366 I2CS_DEBUG("xfer complete in %u jif", (unsigned)(jiffies
- i2cd
->jiffies
));
368 // handle return values (errors and buffers)
370 #if I2CSERIAL_DEBUG==1
373 idx
=sprintf(&tmp_str
[0],"{");
374 for(q
=i2cd
->buffer
; q
<p
; ++q
) {
375 idx
+=sprintf(&tmp_str
[idx
],"%02x,", *q
);
377 idx
+=sprintf(&tmp_str
[idx
],"}");
379 I2CS_DEBUG("error(%d) sending buffer[]=%s", i2cd
->error
, tmp_str
);
385 ret
+=messages
[i
].len
;
388 STAT(i2cserial_stats
.i2c_err
++);
391 } //i2c_serio_i2c_xfer }}}
393 /* {{{ i2c_serio_smbus_xfer : SMBus transfer callback */
394 static s32
i2c_serio_smbus_xfer(struct i2c_adapter
*adapter
,
396 unsigned short flags
,
400 union i2c_smbus_data
*data
)
402 struct serio
*serio
= adapter
->algo_data
;
403 struct i2c_data
*i2cd
= serio_get_drvdata(serio
);
404 unsigned char *p
, *i
;
408 I2CS_DEBUG("J:%lu @%x (rw=%d), cmd%02x, sz%d, dp%p", jiffies
,
409 (unsigned)address
, (int)rw
, (unsigned)command
, (int)size
, data
);
410 STAT(i2cserial_stats
.smbrq
++);
412 if ( ! (i2cd
->state
& I2C_STATE_IDLE
) )
413 wait_event_interruptible_timeout(wq
, (i2cd
->state
&I2C_STATE_IDLE
) == I2C_STATE_IDLE
, TIMEOUT
);
415 if ( ! (i2cd
->state
& I2C_STATE_IDLE
) ) {
416 I2CS_ERR("PSoC jammed..."); /* TODO : reset */
417 i2cd
->state
= I2C_STATE_IDLE
;
425 i2cd
->reply_count
= 1;
430 if (rw
== I2C_SMBUS_WRITE
) {
431 p
= serial_append_write(p
, address
, command
);
432 p
= serial_append_footer(p
);
434 p
= serial_append_read(p
, address
, 1);
438 case I2C_SMBUS_BYTE_DATA
:
439 if (rw
== I2C_SMBUS_WRITE
){
440 p
= serial_append_write(p
, address
, command
);
441 p
= serial_append_escaped_byte(p
, (unsigned char)(data
->byte
& 0xff));
442 p
= serial_append_footer(p
);
444 p
= serial_append_write(p
, address
, command
);
445 p
= serial_append_footer(p
);
446 p
= serial_append_read(p
, address
, 1);
447 i2cd
->reply_count
= 2;
452 * DATA_ALL_SIZE : tweak (see i2c-dev.c) to pass arbitrary size
453 * tweak not needed in future kernel
454 * I think the transition with newer kernel will be smooth:
455 * just remove I2C_SMBUS_I2C_BLOCK_DATA_ALL_SIZE
456 * but verify what I2C_SMBUS_I2C_BLOCK_DATA and I2C_SMBUS_I2C_BLOCK_BROKEN do
458 case I2C_SMBUS_I2C_BLOCK_DATA
:
459 // case I2C_SMBUS_I2C_BLOCK_DATA_ALL_SIZE:
460 if (rw
== I2C_SMBUS_WRITE
) {
461 p
= serial_append_write(p
, address
, command
);
462 for(i
= data
->block
+ 1; i
<= data
->block
+ data
->block
[0]; i
++)
463 p
= serial_append_escaped_byte(p
, *i
);
464 p
= serial_append_footer(p
);
466 I2CS_DEBUG("read_block_data: %d", data
->block
[0]);
467 p
= serial_append_write(p
, address
, command
);
468 p
= serial_append_footer(p
);
469 //we will receive data block + 1 (the size)
470 p
= serial_append_read(p
, address
, data
->block
[0] + 1);
471 i2cd
->reply_count
= 2;
475 case I2C_SMBUS_BLOCK_DATA
:
476 if (rw
== I2C_SMBUS_WRITE
) {
477 p
= serial_append_write(p
, address
, command
);
478 for(i
= data
->block
; i
<= data
->block
+ data
->block
[0]; i
++)
479 p
= serial_append_escaped_byte(p
, *i
);
480 p
= serial_append_footer(p
);
483 * we can't handle this case : because the size is not specified
484 * the psoc need to read the first byte (the size) from the slave
485 * then he can nack when all data is received
487 * psoc doesnt handle this case
489 I2CS_ERR("Unsupported transaction size %d", size
);
494 I2CS_ERR("Unsupported transaction size %d", size
);
499 //i2cd->jiffies = jiffies;
500 if (rw
== I2C_SMBUS_WRITE
) {
501 i2cd
->state
= I2C_STATE_WAIT
;
503 i2cd
->state
= I2C_STATE_READ
;
504 /* prepare irq_buffer */
505 i2cd
->irq_buffer
= &(i2cd
->buffer
[0]);
508 I2CS_DEBUG("send %dB seriobuf", p
-i2cd
->buffer
);
510 /* send command via serio */
512 for (i
= i2cd
->buffer
; i
< p
; i
++) {
513 STAT(i2cserial_stats
.serio_access
++);
514 tmp
+=ret
=serio_write(serio
, *i
);
516 STAT(i2cserial_stats
.serio_err
++);
520 I2CS_DEBUG("serio_write() errors (%d)", -tmp
);
523 /* command is always sent in 0 jiffies ! (buffered)
524 I2CS_DEBUG("command sent in %u jiffies", (unsigned)(jiffies - i2cd->jiffies));
526 i2cd
->jiffies
= jiffies
;
530 wait_event_interruptible_timeout(wq
, (i2cd
->state
& I2C_STATE_IDLE
) == I2C_STATE_IDLE
, TIMEOUT
);
532 if (! (i2cd
->state
& I2C_STATE_IDLE
) ) {
533 #if I2CSERIAL_DEBUG==1
536 idx
=sprintf(&tmp_str
[0],"{");
537 for(i
=i2cd
->buffer
; i
<p
; ++i
) {
538 idx
+=sprintf(&tmp_str
[idx
],"%02x,", *i
);
540 idx
+=sprintf(&tmp_str
[idx
],"}");
542 I2CS_DEBUG("J:%d+%u time out sending buffer[]=%s", i2cd
->jiffies
, (unsigned)(jiffies
- i2cd
->jiffies
), tmp_str
);
544 I2CS_DEBUG("serio_write time out (err:%d), sending reset request...", i2cd
->error
);
545 i2cd
->state
= I2C_STATE_WAIT_WATCHDOG
;
547 STAT(i2cserial_stats
.serio_access
++);
548 ret
=serio_write(serio
, ESCAPE_CHAR
);
550 STAT(i2cserial_stats
.serio_err
++);
553 STAT(i2cserial_stats
.serio_access
++);
554 ret
=serio_write(serio
, CMD_RESET
);
556 STAT(i2cserial_stats
.serio_err
++);
558 wait_event_interruptible_timeout(wq
, i2cd
->state
== I2C_STATE_IDLE
, TIMEOUT
);
563 /* TODO : extended error handling */
565 #if I2CSERIAL_DEBUG==1
568 idx
=sprintf(&tmp_str
[0],"{");
569 for(i
=i2cd
->buffer
; i
<p
; ++i
) {
570 idx
+=sprintf(&tmp_str
[idx
],"%02x,", *i
);
572 idx
+=sprintf(&tmp_str
[idx
],"}");
574 I2CS_DEBUG("error(%d) sending buffer[]=%s", i2cd
->error
, tmp_str
);
581 if (rw
== I2C_SMBUS_READ
) {
582 if (size
== I2C_SMBUS_I2C_BLOCK_DATA_ALL_SIZE
)
585 int sz
= data
->block
[0];
591 I2CS_DEBUG("read_block_data return: %d", sz
);
592 for(j
= 0; j
< sz
; ++j
)
593 data
->block
[j
+1] = i2cd
->buffer
[j
];
596 data
->byte
= i2cd
->buffer
[0];
604 I2CS_DEBUG("xfer complete in %u jif", (unsigned)(jiffies
- i2cd
->jiffies
));
606 STAT(i2cserial_stats
.smb_err
++);
609 } //i2c_serio_smbus_xfer }}}
611 /* {{{ i2c_serio_func ireturn supported I2C/SMBus functionnalities */
612 static u32
i2c_serio_func(struct i2c_adapter
*adapter
)
615 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
616 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
617 I2C_FUNC_SMBUS_I2C_BLOCK;
619 return I2C_FUNC_SMBUS_BYTE
|
620 I2C_FUNC_SMBUS_BYTE_DATA
|
621 I2C_FUNC_SMBUS_BLOCK_DATA
|
622 I2C_FUNC_SMBUS_I2C_BLOCK
;
623 } // i2c_serio_func }}}
625 static const struct i2c_algorithm i2c_algo
= {
626 .master_xfer
= i2c_serio_i2c_xfer
,
627 .smbus_xfer
= i2c_serio_smbus_xfer
,
628 .functionality
= i2c_serio_func
,
631 /* {{{ i2c_interrupt : serial interrupt service routine
632 - store serial data into irqbuffer
634 static irqreturn_t
i2c_interrupt(struct serio
*serio
, unsigned char data
,
637 struct i2c_data
*i2cd
= NULL
;
639 i2cd
= serio_get_drvdata(serio
);
641 I2CS_DEBUG("%02x[%x],%d+%u", (unsigned)data
, flags
, i2cd
->jiffies
, (unsigned)(jiffies
- i2cd
->jiffies
));
643 switch (i2cd
->state
) {
645 /* we're waiting for reply (but no data), we must read [Esc]. Ignore
647 if (data
== ESCAPE_CHAR
) {
648 i2cd
->state
= I2C_STATE_CMD
;
650 //I2CS_DEBUG("Command ACK in %d jiffies", (int)(jiffies - i2cd->jiffies));
656 case ESCAPE_CHAR
: //escaped ESC caracter
657 if (i2cd
->pos
>= I2C_SERIAL_BUFFER_LENGTH
) {
658 I2CS_ERR("Buffer overflow ! (0x%02x)", data
);
660 i2cd
->irq_buffer
[i2cd
->pos
++] = data
;
661 //i2cd->state=I2C_STATE_READ;
665 i2cd
->error
=I2C_ERROR_ADDRNAK
;
666 I2CS_DEBUG("Slave not existing (0x%02x).", data
);
670 i2cd
->error
=I2C_ERROR_NAK
;
671 I2CS_DEBUG("Slave not responding (0x%02x).", data
);
675 i2cd
->error
=I2C_ERROR_OVERBUFF
;
676 I2CS_DEBUG("PSoC buffer overflow.");
680 i2cd
->error
=I2C_ERROR_MTF
;
681 I2CS_DEBUG("Master transmit failure (Wow, how can it happen ?).");
685 i2cd
->error
=I2C_ERROR_STALL
;
686 I2CS_DEBUG("I2C bus stalled.");
690 i2cd
->error
=I2C_ERROR_TIMEOUT
;
691 I2CS_DEBUG("No activity within timeout period.");
694 case REPLY_CANCELREAD
:
695 case REPLY_CANCELWRITE
:
696 i2cd
->error
=I2C_ERROR_BUSY
;
697 I2CS_DEBUG("Device busy (or garbled), command refused.");
701 i2cd
->error
=I2C_ERROR_RESET
;
702 I2CS_DEBUG("Device reset (watchdog timed out).");
708 i2cd
->state
=I2C_STATE_VERSION
;
712 I2CS_DEBUG("Received wakeup command from PSoC.");
716 if (data
>='A' && data
<='Z') {
717 /* write subcommand completed successfully */
721 if (data
>='a' && data
<='z') {
722 /* read subcommand completed successfully */
726 I2CS_INFO("Ignoring unexpected 'ESC-Ox%02x' from PSoC.", data
);
728 if (i2cd
->reply_count
==0) {
729 /* command completed , PSoC will reset soon if no more commands
730 * we must have another wait state, which will not wake_up*/
731 i2cd
->state
= I2C_STATE_WAIT_WATCHDOG
;
732 wake_up_interruptible(&wq
);
734 if (i2cd
->state
!= I2C_STATE_VERSION
) {
735 i2cd
->state
= I2C_STATE_READ
;
740 case I2C_STATE_VERSION
:
741 i2cd
->irq_buffer
[i2cd
->pos
++] = data
;
742 if (--i2cd
->reply_count
== 0) {
743 i2cd
->state
= I2C_STATE_WAIT_WATCHDOG
;
744 wake_up_interruptible(&wq
);
748 case I2C_STATE_WAIT_WATCHDOG
:
749 if (data
==ESCAPE_CHAR
) {
750 //ignore it; if it is a reply, we should be in WAIT state
752 if (data
==CMD_RESET
) {
753 // PSoC WDR complete, nothing more should come
754 i2cd
->state
= I2C_STATE_IDLE
;
759 if (data
==ESCAPE_CHAR
) {
760 i2cd
->state
= I2C_STATE_CMD
;
762 if (i2cd
->pos
>= I2C_SERIAL_BUFFER_LENGTH
) {
763 I2CS_ERR("Buffer overflow !! (0x%02x)", data
);
765 i2cd
->irq_buffer
[i2cd
->pos
++] = data
;
771 /* invalid I2C_STATE */
772 I2CS_DEBUG("Spurious int. data %02x state %d",
773 (unsigned)data
, i2cd
->state
);
776 } // i2c_interrupt }}}
778 /* {{{ i2c_disconnect : serial port disconnection callback */
779 static void i2c_disconnect(struct serio
*serio
)
781 struct i2c_data
*i2cd
= serio_get_drvdata(serio
);
783 i2c_del_adapter(&i2cd
->adapter
);
785 serio_set_drvdata(serio
, NULL
);
787 } // i2c_disconnect }}}
789 /* {{{ i2c_connect : line discipline registration
790 + I2C adapter registration
792 static int i2c_connect(struct serio
*serio
, struct serio_driver
*drv
)
794 struct i2c_data
*i2cd
;
795 struct i2c_adapter
*adapter
;
798 I2CS_DEBUG("i2c_connect");
800 i2cd
= kzalloc(sizeof(struct i2c_data
), GFP_KERNEL
);
805 i2cd
->state
= I2C_STATE_IDLE
;
807 serio_set_drvdata(serio
, i2cd
);
809 I2CS_DEBUG("Opening serio with driver '%s'.", drv
->description
);
811 err
= serio_open(serio
, drv
);
813 I2CS_ERR("serio_open failed %d", err
);
817 adapter
= &i2cd
->adapter
;
818 adapter
->owner
= THIS_MODULE
;
819 adapter
->algo
= &i2c_algo
;
820 adapter
->algo_data
= serio
;
821 adapter
->dev
.parent
= &serio
->dev
;
822 adapter
->id
= I2C_HW_B_SER
;
824 strlcpy(adapter
->name
, DRV_NAME
, strlen(DRV_NAME
));
826 err
= i2c_add_adapter(adapter
);
828 I2CS_DEBUG("adapter registration failed.");
832 I2CS_INFO("I2C over serial port registered.");
834 I2CS_INFO("PSoC firmware version '%s'.", i2c_serial_get_version(adapter
));
841 serio_set_drvdata(serio
, NULL
);
847 /* descripteur du line discipline */
848 static struct serio_device_id i2c_serio_ids
[] = {
857 MODULE_DEVICE_TABLE(serio
, i2c_serio_ids
);
859 /* descripteur du driver serio */
860 static struct serio_driver i2c_drv
= {
864 .description
= "I2C on serial port PSoC (Aldebaran)",
865 .id_table
= i2c_serio_ids
,
866 .connect
= i2c_connect
,
867 .disconnect
= i2c_disconnect
,
868 .interrupt
= i2c_interrupt
,
871 #ifdef I2CSERIAL_STATS
872 /* {{{ proc_i2cstats_read : report debugging statistical info to /proc
873 * TODO check len is always<count !!!! */
874 int proc_i2cstats_read(char* buf
, char** start
, off_t offset
,
875 int count
, int* eof
, void* data
) {
877 len
+= sprintf(buf
+len
,"I2C-serial driver version '%s'\n", VERSION
);
878 len
+= sprintf(buf
+len
,"PSoC firmware version '%s'\n", i2cserial_stats
.firmware_version
);
879 len
+= sprintf(buf
+len
,"I2C_xfr: %8d, %d error(s)\n", i2cserial_stats
.i2crq
, i2cserial_stats
.i2c_err
);
880 len
+= sprintf(buf
+len
,"SMBus : %8d, %d error(s)\n", i2cserial_stats
.smbrq
, i2cserial_stats
.smb_err
);
881 len
+= sprintf(buf
+len
,"Serial : %8ld B, %ld error(s)\n", i2cserial_stats
.serio_access
, i2cserial_stats
.serio_err
);
887 /* initialisation du module et enregistrement du driver serio */
888 static int __init
i2c_serio_init(void)
891 I2CS_INFO("I2C serio driver ver %s", VERSION
);
892 ret
= serio_register_driver(&i2c_drv
);
893 #ifdef I2CSERIAL_STATS
894 for (ret
=0; ret
<sizeof(struct i2cserial_stats__
); ++ret
) {
895 *((char*)(&i2cserial_stats
) + ret
) = '\0';
897 create_proc_read_entry("i2cstats", 0, NULL
, proc_i2cstats_read
, NULL
);
902 static void __exit
i2c_serio_exit(void)
904 STAT(remove_proc_entry("i2cstats", NULL
));
905 serio_unregister_driver(&i2c_drv
);
908 module_init(i2c_serio_init
);
909 module_exit(i2c_serio_exit
);