1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * A FSI master controller, using a simple GPIO bit-banging interface |
4 | */ |
5 | |
6 | #include <linux/crc4.h> |
7 | #include <linux/delay.h> |
8 | #include <linux/device.h> |
9 | #include <linux/fsi.h> |
10 | #include <linux/gpio/consumer.h> |
11 | #include <linux/io.h> |
12 | #include <linux/irqflags.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of.h> |
15 | #include <linux/platform_device.h> |
16 | #include <linux/slab.h> |
17 | |
18 | #include "fsi-master.h" |
19 | |
20 | #define FSI_GPIO_STD_DLY 1 /* Standard pin delay in nS */ |
21 | #define LAST_ADDR_INVALID 0x1 |
22 | |
23 | struct fsi_master_gpio { |
24 | struct fsi_master master; |
25 | struct device *dev; |
26 | struct mutex cmd_lock; /* mutex for command ordering */ |
27 | struct gpio_desc *gpio_clk; |
28 | struct gpio_desc *gpio_data; |
29 | struct gpio_desc *gpio_trans; /* Voltage translator */ |
30 | struct gpio_desc *gpio_enable; /* FSI enable */ |
31 | struct gpio_desc *gpio_mux; /* Mux control */ |
32 | bool external_mode; |
33 | bool no_delays; |
34 | uint32_t last_addr; |
35 | uint8_t t_send_delay; |
36 | uint8_t t_echo_delay; |
37 | }; |
38 | |
39 | #define CREATE_TRACE_POINTS |
40 | #include <trace/events/fsi_master_gpio.h> |
41 | |
42 | #define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master) |
43 | |
44 | struct fsi_gpio_msg { |
45 | uint64_t msg; |
46 | uint8_t bits; |
47 | }; |
48 | |
49 | static void clock_toggle(struct fsi_master_gpio *master, int count) |
50 | { |
51 | int i; |
52 | |
53 | for (i = 0; i < count; i++) { |
54 | if (!master->no_delays) |
55 | ndelay(FSI_GPIO_STD_DLY); |
56 | gpiod_set_value(desc: master->gpio_clk, value: 0); |
57 | if (!master->no_delays) |
58 | ndelay(FSI_GPIO_STD_DLY); |
59 | gpiod_set_value(desc: master->gpio_clk, value: 1); |
60 | } |
61 | } |
62 | |
63 | static int sda_clock_in(struct fsi_master_gpio *master) |
64 | { |
65 | int in; |
66 | |
67 | if (!master->no_delays) |
68 | ndelay(FSI_GPIO_STD_DLY); |
69 | gpiod_set_value(desc: master->gpio_clk, value: 0); |
70 | |
71 | /* Dummy read to feed the synchronizers */ |
72 | gpiod_get_value(desc: master->gpio_data); |
73 | |
74 | /* Actual data read */ |
75 | in = gpiod_get_value(desc: master->gpio_data); |
76 | if (!master->no_delays) |
77 | ndelay(FSI_GPIO_STD_DLY); |
78 | gpiod_set_value(desc: master->gpio_clk, value: 1); |
79 | return in ? 1 : 0; |
80 | } |
81 | |
82 | static void sda_out(struct fsi_master_gpio *master, int value) |
83 | { |
84 | gpiod_set_value(desc: master->gpio_data, value); |
85 | } |
86 | |
87 | static void set_sda_input(struct fsi_master_gpio *master) |
88 | { |
89 | gpiod_direction_input(desc: master->gpio_data); |
90 | gpiod_set_value(desc: master->gpio_trans, value: 0); |
91 | } |
92 | |
93 | static void set_sda_output(struct fsi_master_gpio *master, int value) |
94 | { |
95 | gpiod_set_value(desc: master->gpio_trans, value: 1); |
96 | gpiod_direction_output(desc: master->gpio_data, value); |
97 | } |
98 | |
99 | static void clock_zeros(struct fsi_master_gpio *master, int count) |
100 | { |
101 | trace_fsi_master_gpio_clock_zeros(master, clocks: count); |
102 | set_sda_output(master, value: 1); |
103 | clock_toggle(master, count); |
104 | } |
105 | |
106 | static void echo_delay(struct fsi_master_gpio *master) |
107 | { |
108 | clock_zeros(master, count: master->t_echo_delay); |
109 | } |
110 | |
111 | |
112 | static void serial_in(struct fsi_master_gpio *master, struct fsi_gpio_msg *msg, |
113 | uint8_t num_bits) |
114 | { |
115 | uint8_t bit, in_bit; |
116 | |
117 | set_sda_input(master); |
118 | |
119 | for (bit = 0; bit < num_bits; bit++) { |
120 | in_bit = sda_clock_in(master); |
121 | msg->msg <<= 1; |
122 | msg->msg |= ~in_bit & 0x1; /* Data is active low */ |
123 | } |
124 | msg->bits += num_bits; |
125 | |
126 | trace_fsi_master_gpio_in(master, bits: num_bits, msg: msg->msg); |
127 | } |
128 | |
129 | static void serial_out(struct fsi_master_gpio *master, |
130 | const struct fsi_gpio_msg *cmd) |
131 | { |
132 | uint8_t bit; |
133 | uint64_t msg = ~cmd->msg; /* Data is active low */ |
134 | uint64_t sda_mask = 0x1ULL << (cmd->bits - 1); |
135 | uint64_t last_bit = ~0; |
136 | int next_bit; |
137 | |
138 | trace_fsi_master_gpio_out(master, bits: cmd->bits, msg: cmd->msg); |
139 | |
140 | if (!cmd->bits) { |
141 | dev_warn(master->dev, "trying to output 0 bits\n" ); |
142 | return; |
143 | } |
144 | set_sda_output(master, value: 0); |
145 | |
146 | /* Send the start bit */ |
147 | sda_out(master, value: 0); |
148 | clock_toggle(master, count: 1); |
149 | |
150 | /* Send the message */ |
151 | for (bit = 0; bit < cmd->bits; bit++) { |
152 | next_bit = (msg & sda_mask) >> (cmd->bits - 1); |
153 | if (last_bit ^ next_bit) { |
154 | sda_out(master, value: next_bit); |
155 | last_bit = next_bit; |
156 | } |
157 | clock_toggle(master, count: 1); |
158 | msg <<= 1; |
159 | } |
160 | } |
161 | |
162 | static void msg_push_bits(struct fsi_gpio_msg *msg, uint64_t data, int bits) |
163 | { |
164 | msg->msg <<= bits; |
165 | msg->msg |= data & ((1ull << bits) - 1); |
166 | msg->bits += bits; |
167 | } |
168 | |
169 | static void msg_push_crc(struct fsi_gpio_msg *msg) |
170 | { |
171 | uint8_t crc; |
172 | int top; |
173 | |
174 | top = msg->bits & 0x3; |
175 | |
176 | /* start bit, and any non-aligned top bits */ |
177 | crc = crc4(c: 0, x: 1 << top | msg->msg >> (msg->bits - top), bits: top + 1); |
178 | |
179 | /* aligned bits */ |
180 | crc = crc4(c: crc, x: msg->msg, bits: msg->bits - top); |
181 | |
182 | msg_push_bits(msg, data: crc, bits: 4); |
183 | } |
184 | |
185 | static bool check_same_address(struct fsi_master_gpio *master, int id, |
186 | uint32_t addr) |
187 | { |
188 | /* this will also handle LAST_ADDR_INVALID */ |
189 | return master->last_addr == (((id & 0x3) << 21) | (addr & ~0x3)); |
190 | } |
191 | |
192 | static bool check_relative_address(struct fsi_master_gpio *master, int id, |
193 | uint32_t addr, uint32_t *rel_addrp) |
194 | { |
195 | uint32_t last_addr = master->last_addr; |
196 | int32_t rel_addr; |
197 | |
198 | if (last_addr == LAST_ADDR_INVALID) |
199 | return false; |
200 | |
201 | /* We may be in 23-bit addressing mode, which uses the id as the |
202 | * top two address bits. So, if we're referencing a different ID, |
203 | * use absolute addresses. |
204 | */ |
205 | if (((last_addr >> 21) & 0x3) != id) |
206 | return false; |
207 | |
208 | /* remove the top two bits from any 23-bit addressing */ |
209 | last_addr &= (1 << 21) - 1; |
210 | |
211 | /* We know that the addresses are limited to 21 bits, so this won't |
212 | * overflow the signed rel_addr */ |
213 | rel_addr = addr - last_addr; |
214 | if (rel_addr > 255 || rel_addr < -256) |
215 | return false; |
216 | |
217 | *rel_addrp = (uint32_t)rel_addr; |
218 | |
219 | return true; |
220 | } |
221 | |
222 | static void last_address_update(struct fsi_master_gpio *master, |
223 | int id, bool valid, uint32_t addr) |
224 | { |
225 | if (!valid) |
226 | master->last_addr = LAST_ADDR_INVALID; |
227 | else |
228 | master->last_addr = ((id & 0x3) << 21) | (addr & ~0x3); |
229 | } |
230 | |
231 | /* |
232 | * Encode an Absolute/Relative/Same Address command |
233 | */ |
234 | static void build_ar_command(struct fsi_master_gpio *master, |
235 | struct fsi_gpio_msg *cmd, uint8_t id, |
236 | uint32_t addr, size_t size, const void *data) |
237 | { |
238 | int i, addr_bits, opcode_bits; |
239 | bool write = !!data; |
240 | uint8_t ds, opcode; |
241 | uint32_t rel_addr; |
242 | |
243 | cmd->bits = 0; |
244 | cmd->msg = 0; |
245 | |
246 | /* we have 21 bits of address max */ |
247 | addr &= ((1 << 21) - 1); |
248 | |
249 | /* cmd opcodes are variable length - SAME_AR is only two bits */ |
250 | opcode_bits = 3; |
251 | |
252 | if (check_same_address(master, id, addr)) { |
253 | /* we still address the byte offset within the word */ |
254 | addr_bits = 2; |
255 | opcode_bits = 2; |
256 | opcode = FSI_CMD_SAME_AR; |
257 | trace_fsi_master_gpio_cmd_same_addr(master); |
258 | |
259 | } else if (check_relative_address(master, id, addr, rel_addrp: &rel_addr)) { |
260 | /* 8 bits plus sign */ |
261 | addr_bits = 9; |
262 | addr = rel_addr; |
263 | opcode = FSI_CMD_REL_AR; |
264 | trace_fsi_master_gpio_cmd_rel_addr(master, rel_addr); |
265 | |
266 | } else { |
267 | addr_bits = 21; |
268 | opcode = FSI_CMD_ABS_AR; |
269 | trace_fsi_master_gpio_cmd_abs_addr(master, addr); |
270 | } |
271 | |
272 | /* |
273 | * The read/write size is encoded in the lower bits of the address |
274 | * (as it must be naturally-aligned), and the following ds bit. |
275 | * |
276 | * size addr:1 addr:0 ds |
277 | * 1 x x 0 |
278 | * 2 x 0 1 |
279 | * 4 0 1 1 |
280 | * |
281 | */ |
282 | ds = size > 1 ? 1 : 0; |
283 | addr &= ~(size - 1); |
284 | if (size == 4) |
285 | addr |= 1; |
286 | |
287 | msg_push_bits(msg: cmd, data: id, bits: 2); |
288 | msg_push_bits(msg: cmd, data: opcode, bits: opcode_bits); |
289 | msg_push_bits(msg: cmd, data: write ? 0 : 1, bits: 1); |
290 | msg_push_bits(msg: cmd, data: addr, bits: addr_bits); |
291 | msg_push_bits(msg: cmd, data: ds, bits: 1); |
292 | for (i = 0; write && i < size; i++) |
293 | msg_push_bits(msg: cmd, data: ((uint8_t *)data)[i], bits: 8); |
294 | |
295 | msg_push_crc(msg: cmd); |
296 | } |
297 | |
298 | static void build_dpoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) |
299 | { |
300 | cmd->bits = 0; |
301 | cmd->msg = 0; |
302 | |
303 | msg_push_bits(msg: cmd, data: slave_id, bits: 2); |
304 | msg_push_bits(msg: cmd, FSI_CMD_DPOLL, bits: 3); |
305 | msg_push_crc(msg: cmd); |
306 | } |
307 | |
308 | static void build_epoll_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) |
309 | { |
310 | cmd->bits = 0; |
311 | cmd->msg = 0; |
312 | |
313 | msg_push_bits(msg: cmd, data: slave_id, bits: 2); |
314 | msg_push_bits(msg: cmd, FSI_CMD_EPOLL, bits: 3); |
315 | msg_push_crc(msg: cmd); |
316 | } |
317 | |
318 | static void build_term_command(struct fsi_gpio_msg *cmd, uint8_t slave_id) |
319 | { |
320 | cmd->bits = 0; |
321 | cmd->msg = 0; |
322 | |
323 | msg_push_bits(msg: cmd, data: slave_id, bits: 2); |
324 | msg_push_bits(msg: cmd, FSI_CMD_TERM, bits: 6); |
325 | msg_push_crc(msg: cmd); |
326 | } |
327 | |
328 | /* |
329 | * Note: callers rely specifically on this returning -EAGAIN for |
330 | * a CRC error detected in the response. Use other error code |
331 | * for other situations. It will be converted to something else |
332 | * higher up the stack before it reaches userspace. |
333 | */ |
334 | static int read_one_response(struct fsi_master_gpio *master, |
335 | uint8_t data_size, struct fsi_gpio_msg *msgp, uint8_t *tagp) |
336 | { |
337 | struct fsi_gpio_msg msg; |
338 | unsigned long flags; |
339 | uint32_t crc; |
340 | uint8_t tag; |
341 | int i; |
342 | |
343 | local_irq_save(flags); |
344 | |
345 | /* wait for the start bit */ |
346 | for (i = 0; i < FSI_MASTER_MTOE_COUNT; i++) { |
347 | msg.bits = 0; |
348 | msg.msg = 0; |
349 | serial_in(master, msg: &msg, num_bits: 1); |
350 | if (msg.msg) |
351 | break; |
352 | } |
353 | if (i == FSI_MASTER_MTOE_COUNT) { |
354 | dev_dbg(master->dev, |
355 | "Master time out waiting for response\n" ); |
356 | local_irq_restore(flags); |
357 | return -ETIMEDOUT; |
358 | } |
359 | |
360 | msg.bits = 0; |
361 | msg.msg = 0; |
362 | |
363 | /* Read slave ID & response tag */ |
364 | serial_in(master, msg: &msg, num_bits: 4); |
365 | |
366 | tag = msg.msg & 0x3; |
367 | |
368 | /* If we have an ACK and we're expecting data, clock the data in too */ |
369 | if (tag == FSI_RESP_ACK && data_size) |
370 | serial_in(master, msg: &msg, num_bits: data_size * 8); |
371 | |
372 | /* read CRC */ |
373 | serial_in(master, msg: &msg, FSI_CRC_SIZE); |
374 | |
375 | local_irq_restore(flags); |
376 | |
377 | /* we have a whole message now; check CRC */ |
378 | crc = crc4(c: 0, x: 1, bits: 1); |
379 | crc = crc4(c: crc, x: msg.msg, bits: msg.bits); |
380 | if (crc) { |
381 | /* Check if it's all 1's, that probably means the host is off */ |
382 | if (((~msg.msg) & ((1ull << msg.bits) - 1)) == 0) |
383 | return -ENODEV; |
384 | dev_dbg(master->dev, "ERR response CRC msg: 0x%016llx (%d bits)\n" , |
385 | msg.msg, msg.bits); |
386 | return -EAGAIN; |
387 | } |
388 | |
389 | if (msgp) |
390 | *msgp = msg; |
391 | if (tagp) |
392 | *tagp = tag; |
393 | |
394 | return 0; |
395 | } |
396 | |
397 | static int issue_term(struct fsi_master_gpio *master, uint8_t slave) |
398 | { |
399 | struct fsi_gpio_msg cmd; |
400 | unsigned long flags; |
401 | uint8_t tag; |
402 | int rc; |
403 | |
404 | build_term_command(cmd: &cmd, slave_id: slave); |
405 | |
406 | local_irq_save(flags); |
407 | serial_out(master, cmd: &cmd); |
408 | echo_delay(master); |
409 | local_irq_restore(flags); |
410 | |
411 | rc = read_one_response(master, data_size: 0, NULL, tagp: &tag); |
412 | if (rc < 0) { |
413 | dev_err(master->dev, |
414 | "TERM failed; lost communication with slave\n" ); |
415 | return -EIO; |
416 | } else if (tag != FSI_RESP_ACK) { |
417 | dev_err(master->dev, "TERM failed; response %d\n" , tag); |
418 | return -EIO; |
419 | } |
420 | |
421 | return 0; |
422 | } |
423 | |
424 | static int poll_for_response(struct fsi_master_gpio *master, |
425 | uint8_t slave, uint8_t size, void *data) |
426 | { |
427 | struct fsi_gpio_msg response, cmd; |
428 | int busy_count = 0, rc, i; |
429 | unsigned long flags; |
430 | uint8_t tag; |
431 | uint8_t *data_byte = data; |
432 | int crc_err_retries = 0; |
433 | retry: |
434 | rc = read_one_response(master, data_size: size, msgp: &response, tagp: &tag); |
435 | |
436 | /* Handle retries on CRC errors */ |
437 | if (rc == -EAGAIN) { |
438 | /* Too many retries ? */ |
439 | if (crc_err_retries++ > FSI_CRC_ERR_RETRIES) { |
440 | /* |
441 | * Pass it up as a -EIO otherwise upper level will retry |
442 | * the whole command which isn't what we want here. |
443 | */ |
444 | rc = -EIO; |
445 | goto fail; |
446 | } |
447 | dev_dbg(master->dev, |
448 | "CRC error retry %d\n" , crc_err_retries); |
449 | trace_fsi_master_gpio_crc_rsp_error(master); |
450 | build_epoll_command(cmd: &cmd, slave_id: slave); |
451 | local_irq_save(flags); |
452 | clock_zeros(master, FSI_MASTER_EPOLL_CLOCKS); |
453 | serial_out(master, cmd: &cmd); |
454 | echo_delay(master); |
455 | local_irq_restore(flags); |
456 | goto retry; |
457 | } else if (rc) |
458 | goto fail; |
459 | |
460 | switch (tag) { |
461 | case FSI_RESP_ACK: |
462 | if (size && data) { |
463 | uint64_t val = response.msg; |
464 | /* clear crc & mask */ |
465 | val >>= 4; |
466 | val &= (1ull << (size * 8)) - 1; |
467 | |
468 | for (i = 0; i < size; i++) { |
469 | data_byte[size-i-1] = val; |
470 | val >>= 8; |
471 | } |
472 | } |
473 | break; |
474 | case FSI_RESP_BUSY: |
475 | /* |
476 | * Its necessary to clock slave before issuing |
477 | * d-poll, not indicated in the hardware protocol |
478 | * spec. < 20 clocks causes slave to hang, 21 ok. |
479 | */ |
480 | if (busy_count++ < FSI_MASTER_MAX_BUSY) { |
481 | build_dpoll_command(cmd: &cmd, slave_id: slave); |
482 | local_irq_save(flags); |
483 | clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); |
484 | serial_out(master, cmd: &cmd); |
485 | echo_delay(master); |
486 | local_irq_restore(flags); |
487 | goto retry; |
488 | } |
489 | dev_warn(master->dev, |
490 | "ERR slave is stuck in busy state, issuing TERM\n" ); |
491 | local_irq_save(flags); |
492 | clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); |
493 | local_irq_restore(flags); |
494 | issue_term(master, slave); |
495 | rc = -EIO; |
496 | break; |
497 | |
498 | case FSI_RESP_ERRA: |
499 | dev_dbg(master->dev, "ERRA received: 0x%x\n" , (int)response.msg); |
500 | rc = -EIO; |
501 | break; |
502 | case FSI_RESP_ERRC: |
503 | dev_dbg(master->dev, "ERRC received: 0x%x\n" , (int)response.msg); |
504 | trace_fsi_master_gpio_crc_cmd_error(master); |
505 | rc = -EAGAIN; |
506 | break; |
507 | } |
508 | |
509 | if (busy_count > 0) |
510 | trace_fsi_master_gpio_poll_response_busy(master, busy: busy_count); |
511 | fail: |
512 | /* |
513 | * tSendDelay clocks, avoids signal reflections when switching |
514 | * from receive of response back to send of data. |
515 | */ |
516 | local_irq_save(flags); |
517 | clock_zeros(master, count: master->t_send_delay); |
518 | local_irq_restore(flags); |
519 | |
520 | return rc; |
521 | } |
522 | |
523 | static int send_request(struct fsi_master_gpio *master, |
524 | struct fsi_gpio_msg *cmd) |
525 | { |
526 | unsigned long flags; |
527 | |
528 | if (master->external_mode) |
529 | return -EBUSY; |
530 | |
531 | local_irq_save(flags); |
532 | serial_out(master, cmd); |
533 | echo_delay(master); |
534 | local_irq_restore(flags); |
535 | |
536 | return 0; |
537 | } |
538 | |
539 | static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave, |
540 | struct fsi_gpio_msg *cmd, size_t resp_len, void *resp) |
541 | { |
542 | int rc = -EAGAIN, retries = 0; |
543 | |
544 | while ((retries++) < FSI_CRC_ERR_RETRIES) { |
545 | rc = send_request(master, cmd); |
546 | if (rc) |
547 | break; |
548 | rc = poll_for_response(master, slave, size: resp_len, data: resp); |
549 | if (rc != -EAGAIN) |
550 | break; |
551 | rc = -EIO; |
552 | dev_warn(master->dev, "ECRC retry %d\n" , retries); |
553 | |
554 | /* Pace it a bit before retry */ |
555 | msleep(msecs: 1); |
556 | } |
557 | |
558 | return rc; |
559 | } |
560 | |
561 | static int fsi_master_gpio_read(struct fsi_master *_master, int link, |
562 | uint8_t id, uint32_t addr, void *val, size_t size) |
563 | { |
564 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
565 | struct fsi_gpio_msg cmd; |
566 | int rc; |
567 | |
568 | if (link != 0) |
569 | return -ENODEV; |
570 | |
571 | mutex_lock(&master->cmd_lock); |
572 | build_ar_command(master, cmd: &cmd, id, addr, size, NULL); |
573 | rc = fsi_master_gpio_xfer(master, slave: id, cmd: &cmd, resp_len: size, resp: val); |
574 | last_address_update(master, id, valid: rc == 0, addr); |
575 | mutex_unlock(lock: &master->cmd_lock); |
576 | |
577 | return rc; |
578 | } |
579 | |
580 | static int fsi_master_gpio_write(struct fsi_master *_master, int link, |
581 | uint8_t id, uint32_t addr, const void *val, size_t size) |
582 | { |
583 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
584 | struct fsi_gpio_msg cmd; |
585 | int rc; |
586 | |
587 | if (link != 0) |
588 | return -ENODEV; |
589 | |
590 | mutex_lock(&master->cmd_lock); |
591 | build_ar_command(master, cmd: &cmd, id, addr, size, data: val); |
592 | rc = fsi_master_gpio_xfer(master, slave: id, cmd: &cmd, resp_len: 0, NULL); |
593 | last_address_update(master, id, valid: rc == 0, addr); |
594 | mutex_unlock(lock: &master->cmd_lock); |
595 | |
596 | return rc; |
597 | } |
598 | |
599 | static int fsi_master_gpio_term(struct fsi_master *_master, |
600 | int link, uint8_t id) |
601 | { |
602 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
603 | struct fsi_gpio_msg cmd; |
604 | int rc; |
605 | |
606 | if (link != 0) |
607 | return -ENODEV; |
608 | |
609 | mutex_lock(&master->cmd_lock); |
610 | build_term_command(cmd: &cmd, slave_id: id); |
611 | rc = fsi_master_gpio_xfer(master, slave: id, cmd: &cmd, resp_len: 0, NULL); |
612 | last_address_update(master, id, valid: false, addr: 0); |
613 | mutex_unlock(lock: &master->cmd_lock); |
614 | |
615 | return rc; |
616 | } |
617 | |
618 | static int fsi_master_gpio_break(struct fsi_master *_master, int link) |
619 | { |
620 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
621 | unsigned long flags; |
622 | |
623 | if (link != 0) |
624 | return -ENODEV; |
625 | |
626 | trace_fsi_master_gpio_break(master); |
627 | |
628 | mutex_lock(&master->cmd_lock); |
629 | if (master->external_mode) { |
630 | mutex_unlock(lock: &master->cmd_lock); |
631 | return -EBUSY; |
632 | } |
633 | |
634 | local_irq_save(flags); |
635 | |
636 | set_sda_output(master, value: 1); |
637 | sda_out(master, value: 1); |
638 | clock_toggle(master, FSI_PRE_BREAK_CLOCKS); |
639 | sda_out(master, value: 0); |
640 | clock_toggle(master, FSI_BREAK_CLOCKS); |
641 | echo_delay(master); |
642 | sda_out(master, value: 1); |
643 | clock_toggle(master, FSI_POST_BREAK_CLOCKS); |
644 | |
645 | local_irq_restore(flags); |
646 | |
647 | last_address_update(master, id: 0, valid: false, addr: 0); |
648 | mutex_unlock(lock: &master->cmd_lock); |
649 | |
650 | /* Wait for logic reset to take effect */ |
651 | udelay(200); |
652 | |
653 | return 0; |
654 | } |
655 | |
656 | static void fsi_master_gpio_init(struct fsi_master_gpio *master) |
657 | { |
658 | unsigned long flags; |
659 | |
660 | gpiod_direction_output(desc: master->gpio_mux, value: 1); |
661 | gpiod_direction_output(desc: master->gpio_trans, value: 1); |
662 | gpiod_direction_output(desc: master->gpio_enable, value: 1); |
663 | gpiod_direction_output(desc: master->gpio_clk, value: 1); |
664 | gpiod_direction_output(desc: master->gpio_data, value: 1); |
665 | |
666 | /* todo: evaluate if clocks can be reduced */ |
667 | local_irq_save(flags); |
668 | clock_zeros(master, FSI_INIT_CLOCKS); |
669 | local_irq_restore(flags); |
670 | } |
671 | |
672 | static void fsi_master_gpio_init_external(struct fsi_master_gpio *master) |
673 | { |
674 | gpiod_direction_output(desc: master->gpio_mux, value: 0); |
675 | gpiod_direction_output(desc: master->gpio_trans, value: 0); |
676 | gpiod_direction_output(desc: master->gpio_enable, value: 1); |
677 | gpiod_direction_input(desc: master->gpio_clk); |
678 | gpiod_direction_input(desc: master->gpio_data); |
679 | } |
680 | |
681 | static int fsi_master_gpio_link_enable(struct fsi_master *_master, int link, |
682 | bool enable) |
683 | { |
684 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
685 | int rc = -EBUSY; |
686 | |
687 | if (link != 0) |
688 | return -ENODEV; |
689 | |
690 | mutex_lock(&master->cmd_lock); |
691 | if (!master->external_mode) { |
692 | gpiod_set_value(desc: master->gpio_enable, value: enable ? 1 : 0); |
693 | rc = 0; |
694 | } |
695 | mutex_unlock(lock: &master->cmd_lock); |
696 | |
697 | return rc; |
698 | } |
699 | |
700 | static int fsi_master_gpio_link_config(struct fsi_master *_master, int link, |
701 | u8 t_send_delay, u8 t_echo_delay) |
702 | { |
703 | struct fsi_master_gpio *master = to_fsi_master_gpio(_master); |
704 | |
705 | if (link != 0) |
706 | return -ENODEV; |
707 | |
708 | mutex_lock(&master->cmd_lock); |
709 | master->t_send_delay = t_send_delay; |
710 | master->t_echo_delay = t_echo_delay; |
711 | mutex_unlock(lock: &master->cmd_lock); |
712 | |
713 | return 0; |
714 | } |
715 | |
716 | static ssize_t external_mode_show(struct device *dev, |
717 | struct device_attribute *attr, char *buf) |
718 | { |
719 | struct fsi_master_gpio *master = dev_get_drvdata(dev); |
720 | |
721 | return snprintf(buf, PAGE_SIZE - 1, fmt: "%u\n" , |
722 | master->external_mode ? 1 : 0); |
723 | } |
724 | |
725 | static ssize_t external_mode_store(struct device *dev, |
726 | struct device_attribute *attr, const char *buf, size_t count) |
727 | { |
728 | struct fsi_master_gpio *master = dev_get_drvdata(dev); |
729 | unsigned long val; |
730 | bool external_mode; |
731 | int err; |
732 | |
733 | err = kstrtoul(s: buf, base: 0, res: &val); |
734 | if (err) |
735 | return err; |
736 | |
737 | external_mode = !!val; |
738 | |
739 | mutex_lock(&master->cmd_lock); |
740 | |
741 | if (external_mode == master->external_mode) { |
742 | mutex_unlock(lock: &master->cmd_lock); |
743 | return count; |
744 | } |
745 | |
746 | master->external_mode = external_mode; |
747 | if (master->external_mode) |
748 | fsi_master_gpio_init_external(master); |
749 | else |
750 | fsi_master_gpio_init(master); |
751 | |
752 | mutex_unlock(lock: &master->cmd_lock); |
753 | |
754 | fsi_master_rescan(master: &master->master); |
755 | |
756 | return count; |
757 | } |
758 | |
759 | static DEVICE_ATTR(external_mode, 0664, |
760 | external_mode_show, external_mode_store); |
761 | |
762 | static void fsi_master_gpio_release(struct device *dev) |
763 | { |
764 | struct fsi_master_gpio *master = to_fsi_master_gpio(to_fsi_master(dev)); |
765 | |
766 | of_node_put(node: dev_of_node(dev: master->dev)); |
767 | |
768 | kfree(objp: master); |
769 | } |
770 | |
771 | static int fsi_master_gpio_probe(struct platform_device *pdev) |
772 | { |
773 | struct fsi_master_gpio *master; |
774 | struct gpio_desc *gpio; |
775 | int rc; |
776 | |
777 | master = kzalloc(size: sizeof(*master), GFP_KERNEL); |
778 | if (!master) |
779 | return -ENOMEM; |
780 | |
781 | master->dev = &pdev->dev; |
782 | master->master.dev.parent = master->dev; |
783 | master->master.dev.of_node = of_node_get(node: dev_of_node(dev: master->dev)); |
784 | master->master.dev.release = fsi_master_gpio_release; |
785 | master->last_addr = LAST_ADDR_INVALID; |
786 | |
787 | gpio = devm_gpiod_get(dev: &pdev->dev, con_id: "clock" , flags: 0); |
788 | if (IS_ERR(ptr: gpio)) { |
789 | dev_err(&pdev->dev, "failed to get clock gpio\n" ); |
790 | rc = PTR_ERR(ptr: gpio); |
791 | goto err_free; |
792 | } |
793 | master->gpio_clk = gpio; |
794 | |
795 | gpio = devm_gpiod_get(dev: &pdev->dev, con_id: "data" , flags: 0); |
796 | if (IS_ERR(ptr: gpio)) { |
797 | dev_err(&pdev->dev, "failed to get data gpio\n" ); |
798 | rc = PTR_ERR(ptr: gpio); |
799 | goto err_free; |
800 | } |
801 | master->gpio_data = gpio; |
802 | |
803 | /* Optional GPIOs */ |
804 | gpio = devm_gpiod_get_optional(dev: &pdev->dev, con_id: "trans" , flags: 0); |
805 | if (IS_ERR(ptr: gpio)) { |
806 | dev_err(&pdev->dev, "failed to get trans gpio\n" ); |
807 | rc = PTR_ERR(ptr: gpio); |
808 | goto err_free; |
809 | } |
810 | master->gpio_trans = gpio; |
811 | |
812 | gpio = devm_gpiod_get_optional(dev: &pdev->dev, con_id: "enable" , flags: 0); |
813 | if (IS_ERR(ptr: gpio)) { |
814 | dev_err(&pdev->dev, "failed to get enable gpio\n" ); |
815 | rc = PTR_ERR(ptr: gpio); |
816 | goto err_free; |
817 | } |
818 | master->gpio_enable = gpio; |
819 | |
820 | gpio = devm_gpiod_get_optional(dev: &pdev->dev, con_id: "mux" , flags: 0); |
821 | if (IS_ERR(ptr: gpio)) { |
822 | dev_err(&pdev->dev, "failed to get mux gpio\n" ); |
823 | rc = PTR_ERR(ptr: gpio); |
824 | goto err_free; |
825 | } |
826 | master->gpio_mux = gpio; |
827 | |
828 | /* |
829 | * Check if GPIO block is slow enought that no extra delays |
830 | * are necessary. This improves performance on ast2500 by |
831 | * an order of magnitude. |
832 | */ |
833 | master->no_delays = device_property_present(dev: &pdev->dev, propname: "no-gpio-delays" ); |
834 | |
835 | /* Default FSI command delays */ |
836 | master->t_send_delay = FSI_SEND_DELAY_CLOCKS; |
837 | master->t_echo_delay = FSI_ECHO_DELAY_CLOCKS; |
838 | |
839 | master->master.n_links = 1; |
840 | master->master.flags = FSI_MASTER_FLAG_SWCLOCK; |
841 | master->master.read = fsi_master_gpio_read; |
842 | master->master.write = fsi_master_gpio_write; |
843 | master->master.term = fsi_master_gpio_term; |
844 | master->master.send_break = fsi_master_gpio_break; |
845 | master->master.link_enable = fsi_master_gpio_link_enable; |
846 | master->master.link_config = fsi_master_gpio_link_config; |
847 | platform_set_drvdata(pdev, data: master); |
848 | mutex_init(&master->cmd_lock); |
849 | |
850 | fsi_master_gpio_init(master); |
851 | |
852 | rc = device_create_file(device: &pdev->dev, entry: &dev_attr_external_mode); |
853 | if (rc) |
854 | goto err_free; |
855 | |
856 | rc = fsi_master_register(master: &master->master); |
857 | if (rc) { |
858 | device_remove_file(dev: &pdev->dev, attr: &dev_attr_external_mode); |
859 | put_device(dev: &master->master.dev); |
860 | return rc; |
861 | } |
862 | return 0; |
863 | err_free: |
864 | kfree(objp: master); |
865 | return rc; |
866 | } |
867 | |
868 | |
869 | |
870 | static int fsi_master_gpio_remove(struct platform_device *pdev) |
871 | { |
872 | struct fsi_master_gpio *master = platform_get_drvdata(pdev); |
873 | |
874 | device_remove_file(dev: &pdev->dev, attr: &dev_attr_external_mode); |
875 | |
876 | fsi_master_unregister(master: &master->master); |
877 | |
878 | return 0; |
879 | } |
880 | |
881 | static const struct of_device_id fsi_master_gpio_match[] = { |
882 | { .compatible = "fsi-master-gpio" }, |
883 | { }, |
884 | }; |
885 | MODULE_DEVICE_TABLE(of, fsi_master_gpio_match); |
886 | |
887 | static struct platform_driver fsi_master_gpio_driver = { |
888 | .driver = { |
889 | .name = "fsi-master-gpio" , |
890 | .of_match_table = fsi_master_gpio_match, |
891 | }, |
892 | .probe = fsi_master_gpio_probe, |
893 | .remove = fsi_master_gpio_remove, |
894 | }; |
895 | |
896 | module_platform_driver(fsi_master_gpio_driver); |
897 | MODULE_LICENSE("GPL" ); |
898 | |