1 // SPDX-License-Identifier: GPL-2.0-only
3 * Intel La Jolla Cove Adapter USB-I2C driver
5 * Copyright (c) 2023, Intel Corporation.
8 #include <linux/acpi.h>
9 #include <linux/auxiliary_bus.h>
10 #include <linux/bitfield.h>
11 #include <linux/bits.h>
12 #include <linux/dev_printk.h>
13 #include <linux/i2c.h>
14 #include <linux/module.h>
15 #include <linux/usb/ljca.h>
18 #define LJCA_I2C_INIT_FLAG_MODE BIT(0)
19 #define LJCA_I2C_INIT_FLAG_MODE_POLLING FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 0)
20 #define LJCA_I2C_INIT_FLAG_MODE_INTERRUPT FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 1)
22 #define LJCA_I2C_INIT_FLAG_ADDR_16BIT BIT(0)
24 #define LJCA_I2C_INIT_FLAG_FREQ GENMASK(2, 1)
25 #define LJCA_I2C_INIT_FLAG_FREQ_100K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 0)
26 #define LJCA_I2C_INIT_FLAG_FREQ_400K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 1)
27 #define LJCA_I2C_INIT_FLAG_FREQ_1M FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 2)
29 #define LJCA_I2C_BUF_SIZE 60u
30 #define LJCA_I2C_MAX_XFER_SIZE (LJCA_I2C_BUF_SIZE - sizeof(struct ljca_i2c_rw_packet))
43 LJCA_I2C_WRITE_XFER_TYPE
,
44 LJCA_I2C_READ_XFER_TYPE
,
47 /* I2C raw commands: Init/Start/Read/Write/Stop */
48 struct ljca_i2c_rw_packet
{
51 u8 data
[] __counted_by(len
);
55 struct ljca_client
*ljca
;
56 struct ljca_i2c_info
*i2c_info
;
57 struct i2c_adapter adap
;
59 u8 obuf
[LJCA_I2C_BUF_SIZE
];
60 u8 ibuf
[LJCA_I2C_BUF_SIZE
];
63 static int ljca_i2c_init(struct ljca_i2c_dev
*ljca_i2c
, u8 id
)
65 struct ljca_i2c_rw_packet
*w_packet
=
66 (struct ljca_i2c_rw_packet
*)ljca_i2c
->obuf
;
70 w_packet
->len
= cpu_to_le16(sizeof(*w_packet
->data
));
71 w_packet
->data
[0] = LJCA_I2C_INIT_FLAG_FREQ_400K
;
73 ret
= ljca_transfer(ljca_i2c
->ljca
, LJCA_I2C_INIT
, (u8
*)w_packet
,
74 struct_size(w_packet
, data
, 1), NULL
, 0);
76 return ret
< 0 ? ret
: 0;
79 static int ljca_i2c_start(struct ljca_i2c_dev
*ljca_i2c
, u8 target_addr
,
80 enum ljca_xfer_type type
)
82 struct ljca_i2c_rw_packet
*w_packet
=
83 (struct ljca_i2c_rw_packet
*)ljca_i2c
->obuf
;
84 struct ljca_i2c_rw_packet
*r_packet
=
85 (struct ljca_i2c_rw_packet
*)ljca_i2c
->ibuf
;
89 w_packet
->id
= ljca_i2c
->i2c_info
->id
;
90 w_packet
->len
= cpu_to_le16(sizeof(*w_packet
->data
));
91 w_packet
->data
[0] = (target_addr
<< 1) | type
;
93 ret
= ljca_transfer(ljca_i2c
->ljca
, LJCA_I2C_START
, (u8
*)w_packet
,
94 struct_size(w_packet
, data
, 1), (u8
*)r_packet
,
96 if (ret
< 0 || ret
< sizeof(*r_packet
))
97 return ret
< 0 ? ret
: -EIO
;
99 rp_len
= le16_to_cpu(r_packet
->len
);
100 if (rp_len
< 0 || r_packet
->id
!= w_packet
->id
) {
101 dev_dbg(&ljca_i2c
->adap
.dev
,
102 "i2c start failed len: %d id: %d %d\n",
103 rp_len
, r_packet
->id
, w_packet
->id
);
110 static void ljca_i2c_stop(struct ljca_i2c_dev
*ljca_i2c
)
112 struct ljca_i2c_rw_packet
*w_packet
=
113 (struct ljca_i2c_rw_packet
*)ljca_i2c
->obuf
;
114 struct ljca_i2c_rw_packet
*r_packet
=
115 (struct ljca_i2c_rw_packet
*)ljca_i2c
->ibuf
;
119 w_packet
->id
= ljca_i2c
->i2c_info
->id
;
120 w_packet
->len
= cpu_to_le16(sizeof(*w_packet
->data
));
121 w_packet
->data
[0] = 0;
123 ret
= ljca_transfer(ljca_i2c
->ljca
, LJCA_I2C_STOP
, (u8
*)w_packet
,
124 struct_size(w_packet
, data
, 1), (u8
*)r_packet
,
126 if (ret
< 0 || ret
< sizeof(*r_packet
)) {
127 dev_dbg(&ljca_i2c
->adap
.dev
,
128 "i2c stop failed ret: %d id: %d\n",
133 rp_len
= le16_to_cpu(r_packet
->len
);
134 if (rp_len
< 0 || r_packet
->id
!= w_packet
->id
)
135 dev_dbg(&ljca_i2c
->adap
.dev
,
136 "i2c stop failed len: %d id: %d %d\n",
137 rp_len
, r_packet
->id
, w_packet
->id
);
140 static int ljca_i2c_pure_read(struct ljca_i2c_dev
*ljca_i2c
, u8
*data
, u8 len
)
142 struct ljca_i2c_rw_packet
*w_packet
=
143 (struct ljca_i2c_rw_packet
*)ljca_i2c
->obuf
;
144 struct ljca_i2c_rw_packet
*r_packet
=
145 (struct ljca_i2c_rw_packet
*)ljca_i2c
->ibuf
;
149 w_packet
->id
= ljca_i2c
->i2c_info
->id
;
150 w_packet
->len
= cpu_to_le16(len
);
151 w_packet
->data
[0] = 0;
153 ret
= ljca_transfer(ljca_i2c
->ljca
, LJCA_I2C_READ
, (u8
*)w_packet
,
154 struct_size(w_packet
, data
, 1), (u8
*)r_packet
,
156 if (ret
< 0 || ret
< sizeof(*r_packet
))
157 return ret
< 0 ? ret
: -EIO
;
159 rp_len
= le16_to_cpu(r_packet
->len
);
160 if (rp_len
!= len
|| r_packet
->id
!= w_packet
->id
) {
161 dev_dbg(&ljca_i2c
->adap
.dev
,
162 "i2c raw read failed len: %d id: %d %d\n",
163 rp_len
, r_packet
->id
, w_packet
->id
);
167 memcpy(data
, r_packet
->data
, len
);
172 static int ljca_i2c_read(struct ljca_i2c_dev
*ljca_i2c
, u8 target_addr
, u8
*data
,
177 ret
= ljca_i2c_start(ljca_i2c
, target_addr
, LJCA_I2C_READ_XFER_TYPE
);
179 ret
= ljca_i2c_pure_read(ljca_i2c
, data
, len
);
181 ljca_i2c_stop(ljca_i2c
);
186 static int ljca_i2c_pure_write(struct ljca_i2c_dev
*ljca_i2c
, u8
*data
, u8 len
)
188 struct ljca_i2c_rw_packet
*w_packet
=
189 (struct ljca_i2c_rw_packet
*)ljca_i2c
->obuf
;
190 struct ljca_i2c_rw_packet
*r_packet
=
191 (struct ljca_i2c_rw_packet
*)ljca_i2c
->ibuf
;
195 w_packet
->id
= ljca_i2c
->i2c_info
->id
;
196 w_packet
->len
= cpu_to_le16(len
);
197 memcpy(w_packet
->data
, data
, len
);
199 ret
= ljca_transfer(ljca_i2c
->ljca
, LJCA_I2C_WRITE
, (u8
*)w_packet
,
200 struct_size(w_packet
, data
, len
), (u8
*)r_packet
,
202 if (ret
< 0 || ret
< sizeof(*r_packet
))
203 return ret
< 0 ? ret
: -EIO
;
205 rplen
= le16_to_cpu(r_packet
->len
);
206 if (rplen
!= len
|| r_packet
->id
!= w_packet
->id
) {
207 dev_dbg(&ljca_i2c
->adap
.dev
,
208 "i2c write failed len: %d id: %d/%d\n",
209 rplen
, r_packet
->id
, w_packet
->id
);
216 static int ljca_i2c_write(struct ljca_i2c_dev
*ljca_i2c
, u8 target_addr
,
221 ret
= ljca_i2c_start(ljca_i2c
, target_addr
, LJCA_I2C_WRITE_XFER_TYPE
);
223 ret
= ljca_i2c_pure_write(ljca_i2c
, data
, len
);
225 ljca_i2c_stop(ljca_i2c
);
230 static int ljca_i2c_xfer(struct i2c_adapter
*adapter
, struct i2c_msg
*msg
,
233 struct ljca_i2c_dev
*ljca_i2c
;
234 struct i2c_msg
*cur_msg
;
237 ljca_i2c
= i2c_get_adapdata(adapter
);
241 for (i
= 0; i
< num
; i
++) {
243 if (cur_msg
->flags
& I2C_M_RD
)
244 ret
= ljca_i2c_read(ljca_i2c
, cur_msg
->addr
,
245 cur_msg
->buf
, cur_msg
->len
);
247 ret
= ljca_i2c_write(ljca_i2c
, cur_msg
->addr
,
248 cur_msg
->buf
, cur_msg
->len
);
257 static u32
ljca_i2c_func(struct i2c_adapter
*adap
)
259 return I2C_FUNC_I2C
| (I2C_FUNC_SMBUS_EMUL
& ~I2C_FUNC_SMBUS_QUICK
);
262 static const struct i2c_adapter_quirks ljca_i2c_quirks
= {
263 .flags
= I2C_AQ_NO_ZERO_LEN
,
264 .max_read_len
= LJCA_I2C_MAX_XFER_SIZE
,
265 .max_write_len
= LJCA_I2C_MAX_XFER_SIZE
,
268 static const struct i2c_algorithm ljca_i2c_algo
= {
269 .xfer
= ljca_i2c_xfer
,
270 .functionality
= ljca_i2c_func
,
273 static int ljca_i2c_probe(struct auxiliary_device
*auxdev
,
274 const struct auxiliary_device_id
*aux_dev_id
)
276 struct ljca_client
*ljca
= auxiliary_dev_to_ljca_client(auxdev
);
277 struct ljca_i2c_dev
*ljca_i2c
;
280 ljca_i2c
= devm_kzalloc(&auxdev
->dev
, sizeof(*ljca_i2c
), GFP_KERNEL
);
284 ljca_i2c
->ljca
= ljca
;
285 ljca_i2c
->i2c_info
= dev_get_platdata(&auxdev
->dev
);
287 ljca_i2c
->adap
.owner
= THIS_MODULE
;
288 ljca_i2c
->adap
.class = I2C_CLASS_HWMON
;
289 ljca_i2c
->adap
.algo
= &ljca_i2c_algo
;
290 ljca_i2c
->adap
.quirks
= &ljca_i2c_quirks
;
291 ljca_i2c
->adap
.dev
.parent
= &auxdev
->dev
;
293 snprintf(ljca_i2c
->adap
.name
, sizeof(ljca_i2c
->adap
.name
), "%s-%s-%d",
294 dev_name(&auxdev
->dev
), dev_name(auxdev
->dev
.parent
),
295 ljca_i2c
->i2c_info
->id
);
297 device_set_node(&ljca_i2c
->adap
.dev
, dev_fwnode(&auxdev
->dev
));
299 i2c_set_adapdata(&ljca_i2c
->adap
, ljca_i2c
);
300 auxiliary_set_drvdata(auxdev
, ljca_i2c
);
302 ret
= ljca_i2c_init(ljca_i2c
, ljca_i2c
->i2c_info
->id
);
304 return dev_err_probe(&auxdev
->dev
, -EIO
,
305 "i2c init failed id: %d\n",
306 ljca_i2c
->i2c_info
->id
);
308 ret
= devm_i2c_add_adapter(&auxdev
->dev
, &ljca_i2c
->adap
);
312 if (has_acpi_companion(&ljca_i2c
->adap
.dev
))
313 acpi_dev_clear_dependencies(ACPI_COMPANION(&ljca_i2c
->adap
.dev
));
318 static void ljca_i2c_remove(struct auxiliary_device
*auxdev
)
320 struct ljca_i2c_dev
*ljca_i2c
= auxiliary_get_drvdata(auxdev
);
322 i2c_del_adapter(&ljca_i2c
->adap
);
325 static const struct auxiliary_device_id ljca_i2c_id_table
[] = {
326 { "usb_ljca.ljca-i2c", 0 },
329 MODULE_DEVICE_TABLE(auxiliary
, ljca_i2c_id_table
);
331 static struct auxiliary_driver ljca_i2c_driver
= {
332 .probe
= ljca_i2c_probe
,
333 .remove
= ljca_i2c_remove
,
334 .id_table
= ljca_i2c_id_table
,
336 module_auxiliary_driver(ljca_i2c_driver
);
338 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
339 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
340 MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>");
341 MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-I2C driver");
342 MODULE_LICENSE("GPL");
343 MODULE_IMPORT_NS("LJCA");