diff options
author | Michel Ludwig <michel.ludwig@gmail.com> | 2007-06-29 08:51:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:39:30 -0400 |
commit | 526835d5b30a591578f2813a8837ac70172c0aa9 (patch) | |
tree | 388d311978cd579024ea33e54c8f0ece61946fa8 | |
parent | 0ec4acc6a6405c78a8655687d382ece0daf001b8 (diff) |
V4L/DVB (12778): tm6000: Fix SMBus Read Byte command
Signed-off-by: Michel Ludwig <michel.ludwig@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/tm6000/tm6000-i2c.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c index 5e165ed25eee..80252b746699 100644 --- a/drivers/staging/tm6000/tm6000-i2c.c +++ b/drivers/staging/tm6000/tm6000-i2c.c | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> |
5 | 5 | ||
6 | Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> | ||
7 | - Fix SMBus Read Byte command | ||
8 | |||
6 | This program is free software; you can redistribute it and/or modify | 9 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 10 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation version 2 | 11 | the Free Software Foundation version 2 |
@@ -92,6 +95,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
92 | { | 95 | { |
93 | struct tm6000_core *dev = i2c_adap->algo_data; | 96 | struct tm6000_core *dev = i2c_adap->algo_data; |
94 | int addr, rc, i, byte; | 97 | int addr, rc, i, byte; |
98 | u8 prev_reg = 0; | ||
95 | 99 | ||
96 | if (num <= 0) | 100 | if (num <= 0) |
97 | return 0; | 101 | return 0; |
@@ -100,25 +104,31 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
100 | i2c_dprintk(2,"%s %s addr=0x%x len=%d:", | 104 | i2c_dprintk(2,"%s %s addr=0x%x len=%d:", |
101 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | 105 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", |
102 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | 106 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); |
103 | |||
104 | if (!msgs[i].len) { | 107 | if (!msgs[i].len) { |
105 | /* Do I2C scan */ | 108 | /* Do I2C scan */ |
106 | rc=tm6000_i2c_scan(i2c_adap, addr); | 109 | rc=tm6000_i2c_scan(i2c_adap, addr); |
107 | } else if (msgs[i].flags & I2C_M_RD) { | 110 | } else if (msgs[i].flags & I2C_M_RD) { |
108 | char buf[msgs[i].len]; | ||
109 | memcpy(buf,msgs[i].buf, msgs[i].len-1); | ||
110 | buf[msgs[i].len-1]=0; | ||
111 | |||
112 | /* Read bytes */ | 111 | /* Read bytes */ |
113 | /* I2C is assumed to have always a subaddr at the first byte of the | 112 | /* I2C is assumed to have always a subaddr at the first byte of the |
114 | message bus. Also, the first i2c value of the answer is returned | 113 | message bus. Also, the first i2c value of the answer is returned |
115 | out of message data. | 114 | out of message data. |
116 | */ | 115 | */ |
117 | rc = tm6000_read_write_usb (dev, | 116 | /* SMBus Read Byte command */ |
118 | USB_DIR_IN | USB_TYPE_VENDOR, | 117 | if(msgs[i].len == 1) { |
119 | REQ_16_SET_GET_I2CSEQ, | 118 | // we use the previously used register to read from |
120 | addr|(*msgs[i].buf)<<8, 0, | 119 | rc = tm6000_read_write_usb (dev, |
121 | msgs[i].buf, msgs[i].len); | 120 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
121 | REQ_16_SET_GET_I2CSEQ, | ||
122 | addr | prev_reg<<8, 0, | ||
123 | msgs[i].buf, msgs[i].len); | ||
124 | } | ||
125 | else { | ||
126 | rc = tm6000_read_write_usb (dev, | ||
127 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
128 | REQ_16_SET_GET_I2CSEQ, | ||
129 | addr|(*msgs[i].buf)<<8, 0, | ||
130 | msgs[i].buf, msgs[i].len); | ||
131 | } | ||
122 | if (i2c_debug>=2) { | 132 | if (i2c_debug>=2) { |
123 | for (byte = 0; byte < msgs[i].len; byte++) { | 133 | for (byte = 0; byte < msgs[i].len; byte++) { |
124 | printk(" %02x", msgs[i].buf[byte]); | 134 | printk(" %02x", msgs[i].buf[byte]); |
@@ -136,6 +146,13 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
136 | REQ_16_SET_GET_I2CSEQ, | 146 | REQ_16_SET_GET_I2CSEQ, |
137 | addr|(*msgs[i].buf)<<8, 0, | 147 | addr|(*msgs[i].buf)<<8, 0, |
138 | msgs[i].buf+1, msgs[i].len-1); | 148 | msgs[i].buf+1, msgs[i].len-1); |
149 | |||
150 | if(msgs[i].len >= 1) { | ||
151 | prev_reg = msgs[i].buf[0]; | ||
152 | } | ||
153 | else { | ||
154 | prev_reg = 0; | ||
155 | } | ||
139 | } | 156 | } |
140 | if (i2c_debug>=2) | 157 | if (i2c_debug>=2) |
141 | printk("\n"); | 158 | printk("\n"); |