blob: c179078b8a2e2dc386c5d10198b844ecb3a7f61d [file] [log] [blame]
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +08001/*
2 * I2C bridge driver for the Greybus "generic" I2C module.
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * Released under the GPLv2 only.
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
Alex Eldere1e9dbd2014-10-01 21:54:11 -050013
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +080014#include "greybus.h"
15
Greg Kroah-Hartman199d68d2014-08-30 16:20:22 -070016struct gb_i2c_device {
Alex Eldered8800d2014-10-16 06:35:38 -050017 struct gb_connection *connection;
18 u8 version_major;
19 u8 version_minor;
20
21 u32 functionality;
22 u16 timeout_msec;
23 u8 retries;
24
Alex Elder81f4e222014-10-27 03:48:32 -050025 struct i2c_adapter adapter;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +080026};
27
Alex Eldered8800d2014-10-16 06:35:38 -050028/* Version of the Greybus i2c protocol we support */
29#define GB_I2C_VERSION_MAJOR 0x00
30#define GB_I2C_VERSION_MINOR 0x01
31
32/* Greybus i2c request types */
33#define GB_I2C_TYPE_INVALID 0x00
34#define GB_I2C_TYPE_PROTOCOL_VERSION 0x01
35#define GB_I2C_TYPE_FUNCTIONALITY 0x02
36#define GB_I2C_TYPE_TIMEOUT 0x03
37#define GB_I2C_TYPE_RETRIES 0x04
38#define GB_I2C_TYPE_TRANSFER 0x05
39#define GB_I2C_TYPE_RESPONSE 0x80 /* OR'd with rest */
40
41#define GB_I2C_RETRIES_DEFAULT 3
42#define GB_I2C_TIMEOUT_DEFAULT 1000 /* milliseconds */
43
44/* version request has no payload */
45struct gb_i2c_proto_version_response {
46 __u8 status;
47 __u8 major;
48 __u8 minor;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +080049};
50
Alex Eldered8800d2014-10-16 06:35:38 -050051/* functionality request has no payload */
52struct gb_i2c_functionality_response {
53 __u8 status;
54 __le32 functionality;
55};
56
57struct gb_i2c_timeout_request {
58 __le16 msec;
59};
60struct gb_i2c_timeout_response {
61 __u8 status;
62};
63
64struct gb_i2c_retries_request {
65 __u8 retries;
66};
67struct gb_i2c_retries_response {
68 __u8 status;
69};
70
71/*
72 * Outgoing data immediately follows the op count and ops array.
73 * The data for each write (master -> slave) op in the array is sent
74 * in order, with no (e.g. pad) bytes separating them.
75 *
76 * Short reads cause the entire transfer request to fail So response
77 * payload consists only of bytes read, and the number of bytes is
78 * exactly what was specified in the corresponding op. Like
79 * outgoing data, the incoming data is in order and contiguous.
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +080080 */
Alex Eldered8800d2014-10-16 06:35:38 -050081struct gb_i2c_transfer_op {
82 __le16 addr;
83 __le16 flags;
84 __le16 size;
85};
86
87struct gb_i2c_transfer_request {
88 __le16 op_count;
89 struct gb_i2c_transfer_op ops[0]; /* op_count of these */
90};
91struct gb_i2c_transfer_response {
92 __u8 status;
93 __u8 data[0]; /* inbound data */
94};
95
96/*
97 * This request only uses the connection field, and if successful,
98 * fills in the major and minor protocol version of the target.
99 */
100static int gb_i2c_proto_version_operation(struct gb_i2c_device *gb_i2c_dev)
101{
102 struct gb_connection *connection = gb_i2c_dev->connection;
103 struct gb_operation *operation;
104 struct gb_i2c_proto_version_response *response;
105 int ret;
106
107 /* A protocol version request has no payload */
108 operation = gb_operation_create(connection,
109 GB_I2C_TYPE_PROTOCOL_VERSION,
110 0, sizeof(*response));
111 if (!operation)
112 return -ENOMEM;
113
114 /* Synchronous operation--no callback */
115 ret = gb_operation_request_send(operation, NULL);
116 if (ret) {
117 pr_err("version operation failed (%d)\n", ret);
118 goto out;
119 }
120
121 response = operation->response_payload;
122 if (response->status) {
123 gb_connection_err(connection, "version response %hhu",
124 response->status);
125 ret = -EIO;
126 } else {
127 if (response->major > GB_I2C_VERSION_MAJOR) {
128 pr_err("unsupported major version (%hhu > %hhu)\n",
129 response->major, GB_I2C_VERSION_MAJOR);
130 ret = -ENOTSUPP;
131 goto out;
132 }
133 gb_i2c_dev->version_major = response->major;
134 gb_i2c_dev->version_minor = response->minor;
135 }
136out:
137
138 gb_operation_destroy(operation);
139
140 return ret;
141}
142
143/*
144 * Map Greybus i2c functionality bits into Linux ones
145 */
146static u32 gb_i2c_functionality_map(u32 gb_i2c_functionality)
147{
148 return gb_i2c_functionality; /* All bits the same for now */
149}
150
151static int gb_i2c_functionality_operation(struct gb_i2c_device *gb_i2c_dev)
152{
153 struct gb_connection *connection = gb_i2c_dev->connection;
154 struct gb_operation *operation;
155 struct gb_i2c_functionality_response *response;
156 u32 functionality;
157 int ret;
158
159 /* A functionality request has no payload */
160 operation = gb_operation_create(connection,
161 GB_I2C_TYPE_FUNCTIONALITY,
162 0, sizeof(*response));
163 if (!operation)
164 return -ENOMEM;
165
166 /* Synchronous operation--no callback */
167 ret = gb_operation_request_send(operation, NULL);
168 if (ret) {
169 pr_err("functionality operation failed (%d)\n", ret);
170 goto out;
171 }
172
173 response = operation->response_payload;
174 if (response->status) {
175 gb_connection_err(connection, "functionality response %hhu",
176 response->status);
177 ret = -EIO;
178 } else {
179 functionality = le32_to_cpu(response->functionality);
180 gb_i2c_dev->functionality =
181 gb_i2c_functionality_map(functionality);
182 }
183out:
184 gb_operation_destroy(operation);
185
186 return ret;
187}
188
189static int gb_i2c_timeout_operation(struct gb_i2c_device *gb_i2c_dev, u16 msec)
190{
191 struct gb_connection *connection = gb_i2c_dev->connection;
192 struct gb_operation *operation;
193 struct gb_i2c_timeout_request *request;
194 struct gb_i2c_timeout_response *response;
195 int ret;
196
197 operation = gb_operation_create(connection, GB_I2C_TYPE_TIMEOUT,
198 sizeof(*request), sizeof(*response));
199 if (!operation)
200 return -ENOMEM;
201 request = operation->request_payload;
202 request->msec = cpu_to_le16(msec);
203
204 /* Synchronous operation--no callback */
205 ret = gb_operation_request_send(operation, NULL);
206 if (ret) {
207 pr_err("timeout operation failed (%d)\n", ret);
208 goto out;
209 }
210
211 response = operation->response_payload;
212 if (response->status) {
213 gb_connection_err(connection, "timeout response %hhu",
214 response->status);
215 ret = -EIO;
216 } else {
217 gb_i2c_dev->timeout_msec = msec;
218 }
219out:
220 gb_operation_destroy(operation);
221
222 return ret;
223}
224
225static int gb_i2c_retries_operation(struct gb_i2c_device *gb_i2c_dev,
226 u8 retries)
227{
228 struct gb_connection *connection = gb_i2c_dev->connection;
229 struct gb_operation *operation;
230 struct gb_i2c_retries_request *request;
231 struct gb_i2c_retries_response *response;
232 int ret;
233
234 operation = gb_operation_create(connection, GB_I2C_TYPE_RETRIES,
235 sizeof(*request), sizeof(*response));
236 if (!operation)
237 return -ENOMEM;
238 request = operation->request_payload;
239 request->retries = retries;
240
241 /* Synchronous operation--no callback */
242 ret = gb_operation_request_send(operation, NULL);
243 if (ret) {
244 pr_err("retries operation failed (%d)\n", ret);
245 goto out;
246 }
247
248 response = operation->response_payload;
249 if (response->status) {
250 gb_connection_err(connection, "retries response %hhu",
251 response->status);
252 ret = -EIO;
253 } else {
254 gb_i2c_dev->retries = retries;
255 }
256out:
257 gb_operation_destroy(operation);
258
259 return ret;
260}
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800261
262
Alex Eldered8800d2014-10-16 06:35:38 -0500263/*
264 * Map Linux i2c_msg flags into Greybus i2c transfer op flags.
265 */
266static u16 gb_i2c_transfer_op_flags_map(u16 flags)
267{
268 return flags; /* All flags the same for now */
269}
270
271static void
272gb_i2c_fill_transfer_op(struct gb_i2c_transfer_op *op, struct i2c_msg *msg)
273{
274 u16 flags = gb_i2c_transfer_op_flags_map(msg->flags);
275
276 op->addr = cpu_to_le16(msg->addr);
277 op->flags = cpu_to_le16(flags);
278 op->size = cpu_to_le16(msg->len);
279}
280
281static struct gb_operation *
282gb_i2c_transfer_request(struct gb_connection *connection,
283 struct i2c_msg *msgs, u32 msg_count)
284{
285 struct gb_i2c_transfer_request *request;
286 struct gb_operation *operation;
287 struct gb_i2c_transfer_op *op;
288 struct i2c_msg *msg;
289 u32 data_out_size = 0;
290 u32 data_in_size = 1; /* Response begins with a status byte */
291 size_t request_size;
292 void *data;
293 u16 op_count;
294 u32 i;
295
296 if (msg_count > (u32)U16_MAX) {
297 gb_connection_err(connection, "msg_count (%u) too big",
298 msg_count);
299 return NULL;
300 }
301 op_count = (u16)msg_count;
302
303 /*
304 * In addition to space for all message descriptors we need
305 * to have enough to hold all outbound message data.
306 */
307 msg = msgs;
308 for (i = 0; i < msg_count; i++, msg++)
309 if (msg->flags & I2C_M_RD)
310 data_in_size += (u32)msg->len;
311 else
312 data_out_size += (u32)msg->len;
313
314 request_size = sizeof(struct gb_i2c_transfer_request);
315 request_size += msg_count * sizeof(struct gb_i2c_transfer_op);
316 request_size += data_out_size;
317
318 /* Response consists only of incoming data */
319 operation = gb_operation_create(connection, GB_I2C_TYPE_TRANSFER,
320 request_size, data_in_size);
321 if (!operation)
322 return NULL;
323
324 request = operation->request_payload;
325 request->op_count = cpu_to_le16(op_count);
326 /* Fill in the ops array */
327 op = &request->ops[0];
328 msg = msgs;
329 for (i = 0; i < msg_count; i++)
330 gb_i2c_fill_transfer_op(op++, msg++);
331
332 if (!data_out_size)
333 return operation;
334
335 /* Copy over the outgoing data; it starts after the last op */
336 data = op;
337 msg = msgs;
338 for (i = 0; i < msg_count; i++) {
339 if (!(msg->flags & I2C_M_RD)) {
340 memcpy(data, msg->buf, msg->len);
341 data += msg->len;
342 }
343 msg++;
344 }
345
346 return operation;
347}
348
349static void gb_i2c_transfer_response(struct i2c_msg *msgs, u32 msg_count,
350 void *data)
351{
352 struct i2c_msg *msg = msgs;
353 u32 i;
354
355 for (i = 0; i < msg_count; i++) {
356 if (msg->flags & I2C_M_RD) {
357 memcpy(msg->buf, data, msg->len);
358 data += msg->len;
359 }
360 msg++;
361 }
362}
363
364static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
365 struct i2c_msg *msgs, u32 msg_count)
366{
367 struct gb_connection *connection = gb_i2c_dev->connection;
368 struct gb_i2c_transfer_response *response;
369 struct gb_operation *operation;
370 int ret;
371
372 operation = gb_i2c_transfer_request(connection, msgs, msg_count);
373 if (!operation)
374 return -ENOMEM;
375
376 /* Synchronous operation--no callback */
377 ret = gb_operation_request_send(operation, NULL);
378 if (ret) {
379 pr_err("transfer operation failed (%d)\n", ret);
380 goto out;
381 }
382
383 response = operation->response_payload;
384 if (response->status) {
Alex Elderd7528682014-10-17 05:09:21 -0500385 if (response->status == GB_OP_RETRY) {
386 ret = -EAGAIN;
387 } else {
388 gb_connection_err(connection, "transfer response %hhu",
389 response->status);
390 ret = -EIO;
391 }
Alex Eldered8800d2014-10-16 06:35:38 -0500392 } else {
393 gb_i2c_transfer_response(msgs, msg_count, response->data);
394 ret = msg_count;
395 }
396out:
397 gb_operation_destroy(operation);
398
399 return ret;
400}
401
402static int gb_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
403 int msg_count)
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800404{
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700405 struct gb_i2c_device *gb_i2c_dev;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800406
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700407 gb_i2c_dev = i2c_get_adapdata(adap);
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800408
Alex Eldered8800d2014-10-16 06:35:38 -0500409 return gb_i2c_transfer_operation(gb_i2c_dev, msgs, msg_count);
410}
411
412#if 0
413/* Later */
414static int gb_i2c_smbus_xfer(struct i2c_adapter *adap,
415 u16 addr, unsigned short flags, char read_write,
416 u8 command, int size, union i2c_smbus_data *data)
417{
418 struct gb_i2c_device *gb_i2c_dev;
419
420 gb_i2c_dev = i2c_get_adapdata(adap);
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800421
422 return 0;
423}
Alex Eldered8800d2014-10-16 06:35:38 -0500424#endif
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800425
Alex Eldered8800d2014-10-16 06:35:38 -0500426static u32 gb_i2c_functionality(struct i2c_adapter *adap)
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800427{
Alex Eldered8800d2014-10-16 06:35:38 -0500428 struct gb_i2c_device *gb_i2c_dev = i2c_get_adapdata(adap);
429
430 return gb_i2c_dev->functionality;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800431}
432
Alex Eldered8800d2014-10-16 06:35:38 -0500433static const struct i2c_algorithm gb_i2c_algorithm = {
434 .master_xfer = gb_i2c_master_xfer,
435 /* .smbus_xfer = gb_i2c_smbus_xfer, */
436 .functionality = gb_i2c_functionality,
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800437};
438
Alex Eldered8800d2014-10-16 06:35:38 -0500439/*
440 * Do initial setup of the i2c device. This includes verifying we
441 * can support it (based on the protocol version it advertises).
442 * If that's OK, we get and cached its functionality bits, and
443 * set up the retry count and timeout.
444 *
445 * Note: gb_i2c_dev->connection is assumed to have been valid.
446 */
447static int gb_i2c_device_setup(struct gb_i2c_device *gb_i2c_dev)
448{
449 int ret;
450
451 /* First thing we need to do is check the version */
452 ret = gb_i2c_proto_version_operation(gb_i2c_dev);
453 if (ret)
454 return ret;
455
456 /* Assume the functionality never changes, just get it once */
457 ret = gb_i2c_functionality_operation(gb_i2c_dev);
458 if (ret)
459 return ret;
460
461 /* Set up our default retry count and timeout */
462 ret = gb_i2c_retries_operation(gb_i2c_dev, GB_I2C_RETRIES_DEFAULT);
463 if (ret)
464 return ret;
465
466 return gb_i2c_timeout_operation(gb_i2c_dev, GB_I2C_TIMEOUT_DEFAULT);
467}
468
Alex Elder3689f972014-10-27 06:04:30 -0500469static int gb_i2c_connection_init(struct gb_connection *connection)
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800470{
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700471 struct gb_i2c_device *gb_i2c_dev;
Alex Elder81f4e222014-10-27 03:48:32 -0500472 struct i2c_adapter *adapter;
Alex Eldered8800d2014-10-16 06:35:38 -0500473 int ret;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800474
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700475 gb_i2c_dev = kzalloc(sizeof(*gb_i2c_dev), GFP_KERNEL);
476 if (!gb_i2c_dev)
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800477 return -ENOMEM;
Alex Eldered8800d2014-10-16 06:35:38 -0500478
479 gb_i2c_dev->connection = connection; /* refcount? */
480
481 ret = gb_i2c_device_setup(gb_i2c_dev);
482 if (ret)
483 goto out_err;
484
Alex Elder81f4e222014-10-27 03:48:32 -0500485 /* Looks good; up our i2c adapter */
486 adapter = &gb_i2c_dev->adapter;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800487 adapter->owner = THIS_MODULE;
488 adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
Alex Eldered8800d2014-10-16 06:35:38 -0500489 adapter->algo = &gb_i2c_algorithm;
490 /* adapter->algo_data = what? */
491 adapter->timeout = gb_i2c_dev->timeout_msec * HZ / 1000;
492 adapter->retries = gb_i2c_dev->retries;
493
Greg Kroah-Hartman3e6d5f32014-10-24 18:33:59 +0800494 adapter->dev.parent = &connection->dev;
Greg Kroah-Hartman53419e02014-08-11 17:01:15 +0800495 snprintf(adapter->name, sizeof(adapter->name), "Greybus i2c adapter");
Alex Eldered8800d2014-10-16 06:35:38 -0500496 i2c_set_adapdata(adapter, gb_i2c_dev);
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800497
Alex Eldered8800d2014-10-16 06:35:38 -0500498 ret = i2c_add_adapter(adapter);
499 if (ret)
500 goto out_err;
501
Alex Eldered8800d2014-10-16 06:35:38 -0500502 connection->private = gb_i2c_dev;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800503
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800504 return 0;
Alex Eldered8800d2014-10-16 06:35:38 -0500505out_err:
Alex Eldered8800d2014-10-16 06:35:38 -0500506 /* kref_put(gb_i2c_dev->connection) */
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700507 kfree(gb_i2c_dev);
Alex Eldered8800d2014-10-16 06:35:38 -0500508
509 return ret;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800510}
511
Alex Elder3689f972014-10-27 06:04:30 -0500512static void gb_i2c_connection_exit(struct gb_connection *connection)
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800513{
Alex Eldered8800d2014-10-16 06:35:38 -0500514 struct gb_i2c_device *gb_i2c_dev = connection->private;
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800515
Alex Elder81f4e222014-10-27 03:48:32 -0500516 i2c_del_adapter(&gb_i2c_dev->adapter);
Alex Eldered8800d2014-10-16 06:35:38 -0500517 /* kref_put(gb_i2c_dev->connection) */
Greg Kroah-Hartman3d9efaa2014-08-30 16:49:59 -0700518 kfree(gb_i2c_dev);
Greg Kroah-Hartmanc8a797a2014-08-11 15:30:45 +0800519}
520
Alex Elder19d03de2014-11-05 16:12:53 -0600521static struct gb_protocol i2c_protocol = {
522 .id = GREYBUS_PROTOCOL_I2C,
523 .major = 0,
524 .minor = 1,
Alex Elder5d9fd7e2014-11-05 16:12:54 -0600525 .connection_init = gb_i2c_connection_init,
526 .connection_exit = gb_i2c_connection_exit,
Alex Elderf8fb05e2014-11-05 16:12:55 -0600527 .request_recv = NULL, /* no incoming requests */
Alex Elder19d03de2014-11-05 16:12:53 -0600528};
529
530bool gb_i2c_protocol_init(void)
531{
532 return gb_protocol_register(&i2c_protocol);
533}
534
535void gb_i2c_protocol_exit(void)
536{
537 gb_protocol_deregister(&i2c_protocol);
538}