88#include <linux/mutex.h>
99#include <linux/platform_device.h>
1010#include <linux/regmap.h>
11+ #include <linux/unaligned.h>
1112
1213enum rtl9300_bus_freq {
1314 RTL9300_I2C_STD_FREQ ,
@@ -71,6 +72,22 @@ struct rtl9300_i2c {
7172 struct mutex lock ;
7273};
7374
75+ enum rtl9300_i2c_xfer_type {
76+ RTL9300_I2C_XFER_BYTE ,
77+ RTL9300_I2C_XFER_WORD ,
78+ RTL9300_I2C_XFER_BLOCK ,
79+ };
80+
81+ struct rtl9300_i2c_xfer {
82+ enum rtl9300_i2c_xfer_type type ;
83+ u16 dev_addr ;
84+ u8 reg_addr ;
85+ u8 reg_addr_len ;
86+ u8 * data ;
87+ u8 data_len ;
88+ bool write ;
89+ };
90+
7491#define RTL9300_I2C_MST_CTRL1 0x0
7592#define RTL9300_I2C_MST_CTRL2 0x4
7693#define RTL9300_I2C_MST_DATA_WORD0 0x8
@@ -95,45 +112,37 @@ static int rtl9300_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl)
95112 return regmap_field_write (i2c -> fields [F_SCL_SEL ], 1 );
96113}
97114
98- static int rtl9300_i2c_config_io (struct rtl9300_i2c * i2c , struct rtl9300_i2c_chan * chan )
115+ static int rtl9300_i2c_config_chan (struct rtl9300_i2c * i2c , struct rtl9300_i2c_chan * chan )
99116{
100117 struct rtl9300_i2c_drv_data * drv_data ;
101118 int ret ;
102119
103- drv_data = (struct rtl9300_i2c_drv_data * )device_get_match_data (i2c -> dev );
120+ if (i2c -> sda_num == chan -> sda_num )
121+ return 0 ;
104122
105- ret = regmap_field_update_bits (i2c -> fields [F_SDA_SEL ], BIT (chan -> sda_num ),
106- BIT (chan -> sda_num ));
123+ ret = regmap_field_write (i2c -> fields [F_SCL_FREQ ], chan -> bus_freq );
107124 if (ret )
108125 return ret ;
109126
110- ret = regmap_field_write (i2c -> fields [F_SDA_OUT_SEL ], chan -> sda_num );
127+ drv_data = (struct rtl9300_i2c_drv_data * )device_get_match_data (i2c -> dev );
128+ ret = drv_data -> select_scl (i2c , 0 );
111129 if (ret )
112130 return ret ;
113131
114- ret = regmap_field_write (i2c -> fields [F_SCL_FREQ ], chan -> bus_freq );
132+ ret = regmap_field_update_bits (i2c -> fields [F_SDA_SEL ], BIT (chan -> sda_num ),
133+ BIT (chan -> sda_num ));
115134 if (ret )
116135 return ret ;
117136
118- return drv_data -> select_scl (i2c , 0 );
119- }
120-
121- static int rtl9300_i2c_config_xfer (struct rtl9300_i2c * i2c , struct rtl9300_i2c_chan * chan ,
122- u16 addr , u16 len )
123- {
124- int ret ;
125-
126- if (len < 1 || len > 16 )
127- return - EINVAL ;
128-
129- ret = regmap_field_write (i2c -> fields [F_DEV_ADDR ], addr );
137+ ret = regmap_field_write (i2c -> fields [F_SDA_OUT_SEL ], chan -> sda_num );
130138 if (ret )
131139 return ret ;
132140
133- return regmap_field_write (i2c -> fields [F_DATA_WIDTH ], (len - 1 ) & 0xf );
141+ i2c -> sda_num = chan -> sda_num ;
142+ return 0 ;
134143}
135144
136- static int rtl9300_i2c_read (struct rtl9300_i2c * i2c , u8 * buf , int len )
145+ static int rtl9300_i2c_read (struct rtl9300_i2c * i2c , u8 * buf , u8 len )
137146{
138147 u32 vals [4 ] = {};
139148 int i , ret ;
@@ -153,7 +162,7 @@ static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len)
153162 return 0 ;
154163}
155164
156- static int rtl9300_i2c_write (struct rtl9300_i2c * i2c , u8 * buf , int len )
165+ static int rtl9300_i2c_write (struct rtl9300_i2c * i2c , u8 * buf , u8 len )
157166{
158167 u32 vals [4 ] = {};
159168 int i ;
@@ -176,16 +185,51 @@ static int rtl9300_i2c_writel(struct rtl9300_i2c *i2c, u32 data)
176185 return regmap_write (i2c -> regmap , i2c -> data_reg , data );
177186}
178187
179- static int rtl9300_i2c_execute_xfer (struct rtl9300_i2c * i2c , char read_write ,
180- int size , union i2c_smbus_data * data , int len )
188+ static int rtl9300_i2c_prepare_xfer (struct rtl9300_i2c * i2c , struct rtl9300_i2c_xfer * xfer )
181189{
182- u32 val ;
183190 int ret ;
184191
185- ret = regmap_field_write (i2c -> fields [F_RWOP ], read_write == I2C_SMBUS_WRITE );
192+ if (xfer -> data_len < 1 || xfer -> data_len > 16 )
193+ return - EINVAL ;
194+
195+ ret = regmap_field_write (i2c -> fields [F_DEV_ADDR ], xfer -> dev_addr );
196+ if (ret )
197+ return ret ;
198+
199+ ret = rtl9300_i2c_reg_addr_set (i2c , xfer -> reg_addr , xfer -> reg_addr_len );
200+ if (ret )
201+ return ret ;
202+
203+ ret = regmap_field_write (i2c -> fields [F_RWOP ], xfer -> write );
204+ if (ret )
205+ return ret ;
206+
207+ ret = regmap_field_write (i2c -> fields [F_DATA_WIDTH ], (xfer -> data_len - 1 ) & 0xf );
186208 if (ret )
187209 return ret ;
188210
211+ if (xfer -> write ) {
212+ switch (xfer -> type ) {
213+ case RTL9300_I2C_XFER_BYTE :
214+ ret = rtl9300_i2c_writel (i2c , * xfer -> data );
215+ break ;
216+ case RTL9300_I2C_XFER_WORD :
217+ ret = rtl9300_i2c_writel (i2c , get_unaligned ((const u16 * )xfer -> data ));
218+ break ;
219+ default :
220+ ret = rtl9300_i2c_write (i2c , xfer -> data , xfer -> data_len );
221+ break ;
222+ }
223+ }
224+
225+ return ret ;
226+ }
227+
228+ static int rtl9300_i2c_do_xfer (struct rtl9300_i2c * i2c , struct rtl9300_i2c_xfer * xfer )
229+ {
230+ u32 val ;
231+ int ret ;
232+
189233 ret = regmap_field_write (i2c -> fields [F_I2C_TRIG ], 1 );
190234 if (ret )
191235 return ret ;
@@ -200,28 +244,24 @@ static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,
200244 if (val )
201245 return - EIO ;
202246
203- if (read_write == I2C_SMBUS_READ ) {
204- switch (size ) {
205- case I2C_SMBUS_BYTE :
206- case I2C_SMBUS_BYTE_DATA :
247+ if (!xfer -> write ) {
248+ switch (xfer -> type ) {
249+ case RTL9300_I2C_XFER_BYTE :
207250 ret = regmap_read (i2c -> regmap , i2c -> data_reg , & val );
208251 if (ret )
209252 return ret ;
210- data -> byte = val & 0xff ;
253+
254+ * xfer -> data = val & 0xff ;
211255 break ;
212- case I2C_SMBUS_WORD_DATA :
256+ case RTL9300_I2C_XFER_WORD :
213257 ret = regmap_read (i2c -> regmap , i2c -> data_reg , & val );
214258 if (ret )
215259 return ret ;
216- data -> word = val & 0xffff ;
217- break ;
218- case I2C_SMBUS_I2C_BLOCK_DATA :
219- ret = rtl9300_i2c_read (i2c , & data -> block [1 ], len );
220- if (ret )
221- return ret ;
260+
261+ put_unaligned (val & 0xffff , (u16 * )xfer -> data );
222262 break ;
223263 default :
224- ret = rtl9300_i2c_read (i2c , & data -> block [ 0 ], len );
264+ ret = rtl9300_i2c_read (i2c , xfer -> data , xfer -> data_len );
225265 if (ret )
226266 return ret ;
227267 break ;
@@ -237,108 +277,62 @@ static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned s
237277{
238278 struct rtl9300_i2c_chan * chan = i2c_get_adapdata (adap );
239279 struct rtl9300_i2c * i2c = chan -> i2c ;
240- int len = 0 , ret ;
280+ struct rtl9300_i2c_xfer xfer = {0 };
281+ int ret ;
282+
283+ if (addr > 0x7f )
284+ return - EINVAL ;
241285
242286 mutex_lock (& i2c -> lock );
243- if (chan -> sda_num != i2c -> sda_num ) {
244- ret = rtl9300_i2c_config_io (i2c , chan );
245- if (ret )
246- goto out_unlock ;
247- i2c -> sda_num = chan -> sda_num ;
248- }
287+
288+ ret = rtl9300_i2c_config_chan (i2c , chan );
289+ if (ret )
290+ goto out_unlock ;
291+
292+ xfer .dev_addr = addr & 0x7f ;
293+ xfer .write = (read_write == I2C_SMBUS_WRITE );
294+ xfer .reg_addr = command ;
295+ xfer .reg_addr_len = 1 ;
249296
250297 switch (size ) {
251298 case I2C_SMBUS_BYTE :
252- if (read_write == I2C_SMBUS_WRITE ) {
253- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , 0 );
254- if (ret )
255- goto out_unlock ;
256- ret = rtl9300_i2c_reg_addr_set (i2c , command , 1 );
257- if (ret )
258- goto out_unlock ;
259- } else {
260- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , 1 );
261- if (ret )
262- goto out_unlock ;
263- ret = rtl9300_i2c_reg_addr_set (i2c , 0 , 0 );
264- if (ret )
265- goto out_unlock ;
266- }
299+ xfer .data = (read_write == I2C_SMBUS_READ ) ? & data -> byte : & command ;
300+ xfer .data_len = 1 ;
301+ xfer .reg_addr = 0 ;
302+ xfer .reg_addr_len = 0 ;
303+ xfer .type = RTL9300_I2C_XFER_BYTE ;
267304 break ;
268-
269305 case I2C_SMBUS_BYTE_DATA :
270- ret = rtl9300_i2c_reg_addr_set (i2c , command , 1 );
271- if (ret )
272- goto out_unlock ;
273- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , 1 );
274- if (ret )
275- goto out_unlock ;
276- if (read_write == I2C_SMBUS_WRITE ) {
277- ret = rtl9300_i2c_writel (i2c , data -> byte );
278- if (ret )
279- goto out_unlock ;
280- }
306+ xfer .data = & data -> byte ;
307+ xfer .data_len = 1 ;
308+ xfer .type = RTL9300_I2C_XFER_BYTE ;
281309 break ;
282-
283310 case I2C_SMBUS_WORD_DATA :
284- ret = rtl9300_i2c_reg_addr_set (i2c , command , 1 );
285- if (ret )
286- goto out_unlock ;
287- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , 2 );
288- if (ret )
289- goto out_unlock ;
290- if (read_write == I2C_SMBUS_WRITE ) {
291- ret = rtl9300_i2c_writel (i2c , data -> word );
292- if (ret )
293- goto out_unlock ;
294- }
311+ xfer .data = (u8 * )& data -> word ;
312+ xfer .data_len = 2 ;
313+ xfer .type = RTL9300_I2C_XFER_WORD ;
295314 break ;
296-
297315 case I2C_SMBUS_BLOCK_DATA :
298- ret = rtl9300_i2c_reg_addr_set (i2c , command , 1 );
299- if (ret )
300- goto out_unlock ;
301- if (data -> block [0 ] < 1 || data -> block [0 ] > I2C_SMBUS_BLOCK_MAX ) {
302- ret = - EINVAL ;
303- goto out_unlock ;
304- }
305- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , data -> block [0 ] + 1 );
306- if (ret )
307- goto out_unlock ;
308- if (read_write == I2C_SMBUS_WRITE ) {
309- ret = rtl9300_i2c_write (i2c , & data -> block [0 ], data -> block [0 ] + 1 );
310- if (ret )
311- goto out_unlock ;
312- }
313- len = data -> block [0 ] + 1 ;
316+ xfer .data = & data -> block [0 ];
317+ xfer .data_len = data -> block [0 ] + 1 ;
318+ xfer .type = RTL9300_I2C_XFER_BLOCK ;
314319 break ;
315-
316320 case I2C_SMBUS_I2C_BLOCK_DATA :
317- ret = rtl9300_i2c_reg_addr_set (i2c , command , 1 );
318- if (ret )
319- goto out_unlock ;
320- if (data -> block [0 ] < 1 || data -> block [0 ] > I2C_SMBUS_BLOCK_MAX ) {
321- ret = - EINVAL ;
322- goto out_unlock ;
323- }
324- ret = rtl9300_i2c_config_xfer (i2c , chan , addr , data -> block [0 ]);
325- if (ret )
326- goto out_unlock ;
327- if (read_write == I2C_SMBUS_WRITE ) {
328- ret = rtl9300_i2c_write (i2c , & data -> block [1 ], data -> block [0 ]);
329- if (ret )
330- goto out_unlock ;
331- }
332- len = data -> block [0 ];
321+ xfer .data = & data -> block [1 ];
322+ xfer .data_len = data -> block [0 ];
323+ xfer .type = RTL9300_I2C_XFER_BLOCK ;
333324 break ;
334-
335325 default :
336326 dev_err (& adap -> dev , "Unsupported transaction %d\n" , size );
337327 ret = - EOPNOTSUPP ;
338328 goto out_unlock ;
339329 }
340330
341- ret = rtl9300_i2c_execute_xfer (i2c , read_write , size , data , len );
331+ ret = rtl9300_i2c_prepare_xfer (i2c , & xfer );
332+ if (ret )
333+ goto out_unlock ;
334+
335+ ret = rtl9300_i2c_do_xfer (i2c , & xfer );
342336
343337out_unlock :
344338 mutex_unlock (& i2c -> lock );
0 commit comments