* [PATCH 1/3] i2c i2c-mv64xxx: send repeated START between messages in xfer
@ 2010-11-26 16:06 Rodolfo Giometti
[not found] ` <1290787616-27106-1-git-send-email-giometti-k2GhghHVRtY@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Rodolfo Giometti @ 2010-11-26 16:06 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA; +Cc: Mark A. Greer, Rodolfo Giometti
As stated into file include/linux/i2c.h we must send a repeated START
between messages in the same xfer groupset:
* Except when I2C "protocol mangling" is used, all I2C adapters implement
* the standard rules for I2C transactions. Each transaction begins with a
* START. That is followed by the slave address, and a bit encoding read
* versus write. Then follow all the data bytes, possibly including a byte
* with SMBus PEC. The transfer terminates with a NAK, or when all those
* bytes have been transferred and ACKed. If this is the last message in a
* group, it is followed by a STOP. Otherwise it is followed by the next
* @i2c_msg transaction segment, beginning with a (repeated) START.
Signed-off-by: Rodolfo Giometti <giometti-k2GhghHVRtY@public.gmane.org>
Signed-off-by: Mauro Barella <mbarella-RSoB1PSltFvQT0dZR+AlfA@public.gmane.org>
---
drivers/i2c/busses/i2c-mv64xxx.c | 45 ++++++++++++++++++++++++++++++++------
1 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index c965a24..2cbc5ee 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -59,6 +59,7 @@ enum {
MV64XXX_I2C_STATE_INVALID,
MV64XXX_I2C_STATE_IDLE,
MV64XXX_I2C_STATE_WAITING_FOR_START_COND,
+ MV64XXX_I2C_STATE_WAITING_FOR_RESTART,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
@@ -70,6 +71,7 @@ enum {
MV64XXX_I2C_ACTION_INVALID,
MV64XXX_I2C_ACTION_CONTINUE,
MV64XXX_I2C_ACTION_SEND_START,
+ MV64XXX_I2C_ACTION_SEND_RESTART,
MV64XXX_I2C_ACTION_SEND_ADDR_1,
MV64XXX_I2C_ACTION_SEND_ADDR_2,
MV64XXX_I2C_ACTION_SEND_DATA,
@@ -91,6 +93,7 @@ struct mv64xxx_i2c_data {
u32 addr2;
u32 bytes_left;
u32 byte_posn;
+ u32 send_stop;
u32 block;
int rc;
u32 freq_m;
@@ -159,8 +162,15 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
if ((drv_data->bytes_left == 0)
|| (drv_data->aborting
&& (drv_data->byte_posn != 0))) {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
+ if (drv_data->send_stop) {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
+ drv_data->state = MV64XXX_I2C_STATE_IDLE;
+ } else {
+ drv_data->action =
+ MV64XXX_I2C_ACTION_SEND_RESTART;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_RESTART;
+ }
} else {
drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
drv_data->state =
@@ -228,6 +238,15 @@ static void
mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
{
switch(drv_data->action) {
+ case MV64XXX_I2C_ACTION_SEND_RESTART:
+ drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
+ drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
+ writel(drv_data->cntl_bits,
+ drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->block = 0;
+ wake_up_interruptible(&drv_data->waitq);
+ break;
+
case MV64XXX_I2C_ACTION_CONTINUE:
writel(drv_data->cntl_bits,
drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
@@ -386,7 +405,8 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
}
static int
-mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg)
+mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
+ int is_first, int is_last)
{
unsigned long flags;
@@ -406,10 +426,18 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg)
drv_data->bytes_left--;
}
} else {
- drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
- drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+ if (is_first) {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+ } else {
+ drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
+ drv_data->state =
+ MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
+ }
}
+ drv_data->send_stop = is_last;
drv_data->block = 1;
mv64xxx_i2c_do_action(drv_data);
spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -437,9 +465,12 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
int i, rc;
- for (i=0; i<num; i++)
- if ((rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i])) < 0)
+ for (i = 0; i < num; i++) {
+ rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i],
+ i == 0, i + 1 == num);
+ if (rc < 0)
return rc;
+ }
return num;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/3] i2c i2c-mv64xxx: send repeated START between messages in xfer
[not found] ` <1290787616-27106-1-git-send-email-giometti-k2GhghHVRtY@public.gmane.org>
@ 2010-12-03 2:30 ` Ben Dooks
[not found] ` <20101203023020.GE20097-SMNkleLxa3Z6Wcw2j4pizdi2O/JbrIOy@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Ben Dooks @ 2010-12-03 2:30 UTC (permalink / raw)
To: Rodolfo Giometti; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Mark A. Greer
On Fri, Nov 26, 2010 at 05:06:56PM +0100, Rodolfo Giometti wrote:
> As stated into file include/linux/i2c.h we must send a repeated START
> between messages in the same xfer groupset:
patch says 1/3, but only one turned up?
> * Except when I2C "protocol mangling" is used, all I2C adapters implement
> * the standard rules for I2C transactions. Each transaction begins with a
> * START. That is followed by the slave address, and a bit encoding read
> * versus write. Then follow all the data bytes, possibly including a byte
> * with SMBus PEC. The transfer terminates with a NAK, or when all those
> * bytes have been transferred and ACKed. If this is the last message in a
> * group, it is followed by a STOP. Otherwise it is followed by the next
> * @i2c_msg transaction segment, beginning with a (repeated) START.
>
> Signed-off-by: Rodolfo Giometti <giometti-k2GhghHVRtY@public.gmane.org>
> Signed-off-by: Mauro Barella <mbarella-RSoB1PSltFvQT0dZR+AlfA@public.gmane.org>
> ---
> drivers/i2c/busses/i2c-mv64xxx.c | 45 ++++++++++++++++++++++++++++++++------
Anyone got any commentson whether this is an -rc fix or for next merge
window... I'd be tempted to merge it as soon as possible.
--
Ben
Q: What's a light-year?
A: One-third less calories than a regular year.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 1/3] i2c i2c-mv64xxx: send repeated START between messages in xfer
[not found] ` <20101203023020.GE20097-SMNkleLxa3Z6Wcw2j4pizdi2O/JbrIOy@public.gmane.org>
@ 2010-12-03 8:28 ` Rodolfo Giometti
0 siblings, 0 replies; 3+ messages in thread
From: Rodolfo Giometti @ 2010-12-03 8:28 UTC (permalink / raw)
To: Ben Dooks; +Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, Mark A. Greer
On Fri, Dec 03, 2010 at 02:30:20AM +0000, Ben Dooks wrote:
> On Fri, Nov 26, 2010 at 05:06:56PM +0100, Rodolfo Giometti wrote:
> > As stated into file include/linux/i2c.h we must send a repeated START
> > between messages in the same xfer groupset:
>
> patch says 1/3, but only one turned up?
Yes, sorry. It was my mistake in numbering the patch. :'( This is the
only patch regarding this topic.
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti-AVVDYK/kqiJWk0Htik3J/w@public.gmane.org
Linux Device Driver giometti-k2GhghHVRtY@public.gmane.org
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-12-03 8:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-26 16:06 [PATCH 1/3] i2c i2c-mv64xxx: send repeated START between messages in xfer Rodolfo Giometti
[not found] ` <1290787616-27106-1-git-send-email-giometti-k2GhghHVRtY@public.gmane.org>
2010-12-03 2:30 ` Ben Dooks
[not found] ` <20101203023020.GE20097-SMNkleLxa3Z6Wcw2j4pizdi2O/JbrIOy@public.gmane.org>
2010-12-03 8:28 ` Rodolfo Giometti
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).