Lines Matching +full:fsi +full:- +full:master
1 // SPDX-License-Identifier: GPL-2.0-only
3 * A FSI master controller, using a simple GPIO bit-banging interface
9 #include <linux/fsi.h>
18 #include "fsi-master.h"
24 struct fsi_master master; member
30 struct gpio_desc *gpio_enable; /* FSI enable */
42 #define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
49 static void clock_toggle(struct fsi_master_gpio *master, int count) in clock_toggle() argument
54 if (!master->no_delays) in clock_toggle()
56 gpiod_set_value(master->gpio_clk, 0); in clock_toggle()
57 if (!master->no_delays) in clock_toggle()
59 gpiod_set_value(master->gpio_clk, 1); in clock_toggle()
63 static int sda_clock_in(struct fsi_master_gpio *master) in sda_clock_in() argument
67 if (!master->no_delays) in sda_clock_in()
69 gpiod_set_value(master->gpio_clk, 0); in sda_clock_in()
72 gpiod_get_value(master->gpio_data); in sda_clock_in()
75 in = gpiod_get_value(master->gpio_data); in sda_clock_in()
76 if (!master->no_delays) in sda_clock_in()
78 gpiod_set_value(master->gpio_clk, 1); in sda_clock_in()
82 static void sda_out(struct fsi_master_gpio *master, int value) in sda_out() argument
84 gpiod_set_value(master->gpio_data, value); in sda_out()
87 static void set_sda_input(struct fsi_master_gpio *master) in set_sda_input() argument
89 gpiod_direction_input(master->gpio_data); in set_sda_input()
90 gpiod_set_value(master->gpio_trans, 0); in set_sda_input()
93 static void set_sda_output(struct fsi_master_gpio *master, int value) in set_sda_output() argument
95 gpiod_set_value(master->gpio_trans, 1); in set_sda_output()
96 gpiod_direction_output(master->gpio_data, value); in set_sda_output()
99 static void clock_zeros(struct fsi_master_gpio *master, int count) in clock_zeros() argument
101 trace_fsi_master_gpio_clock_zeros(master, count); in clock_zeros()
102 set_sda_output(master, 1); in clock_zeros()
103 clock_toggle(master, count); in clock_zeros()
106 static void echo_delay(struct fsi_master_gpio *master) in echo_delay() argument
108 clock_zeros(master, master->t_echo_delay); in echo_delay()
112 static void serial_in(struct fsi_master_gpio *master, struct fsi_gpio_msg *msg, in serial_in() argument
117 set_sda_input(master); in serial_in()
120 in_bit = sda_clock_in(master); in serial_in()
121 msg->msg <<= 1; in serial_in()
122 msg->msg |= ~in_bit & 0x1; /* Data is active low */ in serial_in()
124 msg->bits += num_bits; in serial_in()
126 trace_fsi_master_gpio_in(master, num_bits, msg->msg); in serial_in()
129 static void serial_out(struct fsi_master_gpio *master, in serial_out() argument
133 uint64_t msg = ~cmd->msg; /* Data is active low */ in serial_out()
134 uint64_t sda_mask = 0x1ULL << (cmd->bits - 1); in serial_out()
138 trace_fsi_master_gpio_out(master, cmd->bits, cmd->msg); in serial_out()
140 if (!cmd->bits) { in serial_out()
141 dev_warn(master->dev, "trying to output 0 bits\n"); in serial_out()
144 set_sda_output(master, 0); in serial_out()
147 sda_out(master, 0); in serial_out()
148 clock_toggle(master, 1); in serial_out()
151 for (bit = 0; bit < cmd->bits; bit++) { in serial_out()
152 next_bit = (msg & sda_mask) >> (cmd->bits - 1); in serial_out()
154 sda_out(master, next_bit); in serial_out()
157 clock_toggle(master, 1); in serial_out()
164 msg->msg <<= bits; in msg_push_bits()
165 msg->msg |= data & ((1ull << bits) - 1); in msg_push_bits()
166 msg->bits += bits; in msg_push_bits()
174 top = msg->bits & 0x3; in msg_push_crc()
176 /* start bit, and any non-aligned top bits */ in msg_push_crc()
177 crc = crc4(0, 1 << top | msg->msg >> (msg->bits - top), top + 1); in msg_push_crc()
180 crc = crc4(crc, msg->msg, msg->bits - top); in msg_push_crc()
185 static bool check_same_address(struct fsi_master_gpio *master, int id, in check_same_address() argument
189 return master->last_addr == (((id & 0x3) << 21) | (addr & ~0x3)); in check_same_address()
192 static bool check_relative_address(struct fsi_master_gpio *master, int id, in check_relative_address() argument
195 uint32_t last_addr = master->last_addr; in check_relative_address()
201 /* We may be in 23-bit addressing mode, which uses the id as the in check_relative_address()
208 /* remove the top two bits from any 23-bit addressing */ in check_relative_address()
209 last_addr &= (1 << 21) - 1; in check_relative_address()
213 rel_addr = addr - last_addr; in check_relative_address()
214 if (rel_addr > 255 || rel_addr < -256) in check_relative_address()
222 static void last_address_update(struct fsi_master_gpio *master, in last_address_update() argument
226 master->last_addr = LAST_ADDR_INVALID; in last_address_update()
228 master->last_addr = ((id & 0x3) << 21) | (addr & ~0x3); in last_address_update()
234 static void build_ar_command(struct fsi_master_gpio *master, in build_ar_command() argument
243 cmd->bits = 0; in build_ar_command()
244 cmd->msg = 0; in build_ar_command()
247 addr &= ((1 << 21) - 1); in build_ar_command()
249 /* cmd opcodes are variable length - SAME_AR is only two bits */ in build_ar_command()
252 if (check_same_address(master, id, addr)) { in build_ar_command()
257 trace_fsi_master_gpio_cmd_same_addr(master); in build_ar_command()
259 } else if (check_relative_address(master, id, addr, &rel_addr)) { in build_ar_command()
264 trace_fsi_master_gpio_cmd_rel_addr(master, rel_addr); in build_ar_command()
269 trace_fsi_master_gpio_cmd_abs_addr(master, addr); in build_ar_command()
274 * (as it must be naturally-aligned), and the following ds bit. in build_ar_command()
283 addr &= ~(size - 1); in build_ar_command()
300 cmd->bits = 0; in build_dpoll_command()
301 cmd->msg = 0; in build_dpoll_command()
310 cmd->bits = 0; in build_epoll_command()
311 cmd->msg = 0; in build_epoll_command()
320 cmd->bits = 0; in build_term_command()
321 cmd->msg = 0; in build_term_command()
329 * Note: callers rely specifically on this returning -EAGAIN for
334 static int read_one_response(struct fsi_master_gpio *master, in read_one_response() argument
349 serial_in(master, &msg, 1); in read_one_response()
354 dev_dbg(master->dev, in read_one_response()
355 "Master time out waiting for response\n"); in read_one_response()
357 return -ETIMEDOUT; in read_one_response()
364 serial_in(master, &msg, 4); in read_one_response()
370 serial_in(master, &msg, data_size * 8); in read_one_response()
373 serial_in(master, &msg, FSI_CRC_SIZE); in read_one_response()
382 if (((~msg.msg) & ((1ull << msg.bits) - 1)) == 0) in read_one_response()
383 return -ENODEV; in read_one_response()
384 dev_dbg(master->dev, "ERR response CRC msg: 0x%016llx (%d bits)\n", in read_one_response()
386 return -EAGAIN; in read_one_response()
397 static int issue_term(struct fsi_master_gpio *master, uint8_t slave) in issue_term() argument
407 serial_out(master, &cmd); in issue_term()
408 echo_delay(master); in issue_term()
411 rc = read_one_response(master, 0, NULL, &tag); in issue_term()
413 dev_err(master->dev, in issue_term()
415 return -EIO; in issue_term()
417 dev_err(master->dev, "TERM failed; response %d\n", tag); in issue_term()
418 return -EIO; in issue_term()
424 static int poll_for_response(struct fsi_master_gpio *master, in poll_for_response() argument
434 rc = read_one_response(master, size, &response, &tag); in poll_for_response()
437 if (rc == -EAGAIN) { in poll_for_response()
441 * Pass it up as a -EIO otherwise upper level will retry in poll_for_response()
444 rc = -EIO; in poll_for_response()
447 dev_dbg(master->dev, in poll_for_response()
449 trace_fsi_master_gpio_crc_rsp_error(master); in poll_for_response()
452 clock_zeros(master, FSI_MASTER_EPOLL_CLOCKS); in poll_for_response()
453 serial_out(master, &cmd); in poll_for_response()
454 echo_delay(master); in poll_for_response()
466 val &= (1ull << (size * 8)) - 1; in poll_for_response()
469 data_byte[size-i-1] = val; in poll_for_response()
477 * d-poll, not indicated in the hardware protocol in poll_for_response()
483 clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); in poll_for_response()
484 serial_out(master, &cmd); in poll_for_response()
485 echo_delay(master); in poll_for_response()
489 dev_warn(master->dev, in poll_for_response()
492 clock_zeros(master, FSI_MASTER_DPOLL_CLOCKS); in poll_for_response()
494 issue_term(master, slave); in poll_for_response()
495 rc = -EIO; in poll_for_response()
499 dev_dbg(master->dev, "ERRA received: 0x%x\n", (int)response.msg); in poll_for_response()
500 rc = -EIO; in poll_for_response()
503 dev_dbg(master->dev, "ERRC received: 0x%x\n", (int)response.msg); in poll_for_response()
504 trace_fsi_master_gpio_crc_cmd_error(master); in poll_for_response()
505 rc = -EAGAIN; in poll_for_response()
510 trace_fsi_master_gpio_poll_response_busy(master, busy_count); in poll_for_response()
517 clock_zeros(master, master->t_send_delay); in poll_for_response()
523 static int send_request(struct fsi_master_gpio *master, in send_request() argument
528 if (master->external_mode) in send_request()
529 return -EBUSY; in send_request()
532 serial_out(master, cmd); in send_request()
533 echo_delay(master); in send_request()
539 static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave, in fsi_master_gpio_xfer() argument
542 int rc = -EAGAIN, retries = 0; in fsi_master_gpio_xfer()
545 rc = send_request(master, cmd); in fsi_master_gpio_xfer()
548 rc = poll_for_response(master, slave, resp_len, resp); in fsi_master_gpio_xfer()
549 if (rc != -EAGAIN) in fsi_master_gpio_xfer()
551 rc = -EIO; in fsi_master_gpio_xfer()
552 dev_warn(master->dev, "ECRC retry %d\n", retries); in fsi_master_gpio_xfer()
564 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_read() local
569 return -ENODEV; in fsi_master_gpio_read()
571 mutex_lock(&master->cmd_lock); in fsi_master_gpio_read()
572 build_ar_command(master, &cmd, id, addr, size, NULL); in fsi_master_gpio_read()
573 rc = fsi_master_gpio_xfer(master, id, &cmd, size, val); in fsi_master_gpio_read()
574 last_address_update(master, id, rc == 0, addr); in fsi_master_gpio_read()
575 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_read()
583 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_write() local
588 return -ENODEV; in fsi_master_gpio_write()
590 mutex_lock(&master->cmd_lock); in fsi_master_gpio_write()
591 build_ar_command(master, &cmd, id, addr, size, val); in fsi_master_gpio_write()
592 rc = fsi_master_gpio_xfer(master, id, &cmd, 0, NULL); in fsi_master_gpio_write()
593 last_address_update(master, id, rc == 0, addr); in fsi_master_gpio_write()
594 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_write()
602 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_term() local
607 return -ENODEV; in fsi_master_gpio_term()
609 mutex_lock(&master->cmd_lock); in fsi_master_gpio_term()
611 rc = fsi_master_gpio_xfer(master, id, &cmd, 0, NULL); in fsi_master_gpio_term()
612 last_address_update(master, id, false, 0); in fsi_master_gpio_term()
613 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_term()
620 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_break() local
624 return -ENODEV; in fsi_master_gpio_break()
626 trace_fsi_master_gpio_break(master); in fsi_master_gpio_break()
628 mutex_lock(&master->cmd_lock); in fsi_master_gpio_break()
629 if (master->external_mode) { in fsi_master_gpio_break()
630 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_break()
631 return -EBUSY; in fsi_master_gpio_break()
636 set_sda_output(master, 1); in fsi_master_gpio_break()
637 sda_out(master, 1); in fsi_master_gpio_break()
638 clock_toggle(master, FSI_PRE_BREAK_CLOCKS); in fsi_master_gpio_break()
639 sda_out(master, 0); in fsi_master_gpio_break()
640 clock_toggle(master, FSI_BREAK_CLOCKS); in fsi_master_gpio_break()
641 echo_delay(master); in fsi_master_gpio_break()
642 sda_out(master, 1); in fsi_master_gpio_break()
643 clock_toggle(master, FSI_POST_BREAK_CLOCKS); in fsi_master_gpio_break()
647 last_address_update(master, 0, false, 0); in fsi_master_gpio_break()
648 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_break()
656 static void fsi_master_gpio_init(struct fsi_master_gpio *master) in fsi_master_gpio_init() argument
660 gpiod_direction_output(master->gpio_mux, 1); in fsi_master_gpio_init()
661 gpiod_direction_output(master->gpio_trans, 1); in fsi_master_gpio_init()
662 gpiod_direction_output(master->gpio_enable, 1); in fsi_master_gpio_init()
663 gpiod_direction_output(master->gpio_clk, 1); in fsi_master_gpio_init()
664 gpiod_direction_output(master->gpio_data, 1); in fsi_master_gpio_init()
668 clock_zeros(master, FSI_INIT_CLOCKS); in fsi_master_gpio_init()
672 static void fsi_master_gpio_init_external(struct fsi_master_gpio *master) in fsi_master_gpio_init_external() argument
674 gpiod_direction_output(master->gpio_mux, 0); in fsi_master_gpio_init_external()
675 gpiod_direction_output(master->gpio_trans, 0); in fsi_master_gpio_init_external()
676 gpiod_direction_output(master->gpio_enable, 1); in fsi_master_gpio_init_external()
677 gpiod_direction_input(master->gpio_clk); in fsi_master_gpio_init_external()
678 gpiod_direction_input(master->gpio_data); in fsi_master_gpio_init_external()
684 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_link_enable() local
685 int rc = -EBUSY; in fsi_master_gpio_link_enable()
688 return -ENODEV; in fsi_master_gpio_link_enable()
690 mutex_lock(&master->cmd_lock); in fsi_master_gpio_link_enable()
691 if (!master->external_mode) { in fsi_master_gpio_link_enable()
692 gpiod_set_value(master->gpio_enable, enable ? 1 : 0); in fsi_master_gpio_link_enable()
695 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_link_enable()
703 struct fsi_master_gpio *master = to_fsi_master_gpio(_master); in fsi_master_gpio_link_config() local
706 return -ENODEV; in fsi_master_gpio_link_config()
708 mutex_lock(&master->cmd_lock); in fsi_master_gpio_link_config()
709 master->t_send_delay = t_send_delay; in fsi_master_gpio_link_config()
710 master->t_echo_delay = t_echo_delay; in fsi_master_gpio_link_config()
711 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_link_config()
719 struct fsi_master_gpio *master = dev_get_drvdata(dev); in external_mode_show() local
721 return snprintf(buf, PAGE_SIZE - 1, "%u\n", in external_mode_show()
722 master->external_mode ? 1 : 0); in external_mode_show()
728 struct fsi_master_gpio *master = dev_get_drvdata(dev); in external_mode_store() local
739 mutex_lock(&master->cmd_lock); in external_mode_store()
741 if (external_mode == master->external_mode) { in external_mode_store()
742 mutex_unlock(&master->cmd_lock); in external_mode_store()
746 master->external_mode = external_mode; in external_mode_store()
747 if (master->external_mode) in external_mode_store()
748 fsi_master_gpio_init_external(master); in external_mode_store()
750 fsi_master_gpio_init(master); in external_mode_store()
752 mutex_unlock(&master->cmd_lock); in external_mode_store()
754 fsi_master_rescan(&master->master); in external_mode_store()
764 struct fsi_master_gpio *master = to_fsi_master_gpio(to_fsi_master(dev)); in fsi_master_gpio_release() local
766 of_node_put(dev_of_node(master->dev)); in fsi_master_gpio_release()
768 kfree(master); in fsi_master_gpio_release()
773 struct fsi_master_gpio *master; in fsi_master_gpio_probe() local
777 master = kzalloc(sizeof(*master), GFP_KERNEL); in fsi_master_gpio_probe()
778 if (!master) in fsi_master_gpio_probe()
779 return -ENOMEM; in fsi_master_gpio_probe()
781 master->dev = &pdev->dev; in fsi_master_gpio_probe()
782 master->master.dev.parent = master->dev; in fsi_master_gpio_probe()
783 master->master.dev.of_node = of_node_get(dev_of_node(master->dev)); in fsi_master_gpio_probe()
784 master->master.dev.release = fsi_master_gpio_release; in fsi_master_gpio_probe()
785 master->last_addr = LAST_ADDR_INVALID; in fsi_master_gpio_probe()
787 gpio = devm_gpiod_get(&pdev->dev, "clock", 0); in fsi_master_gpio_probe()
789 dev_err(&pdev->dev, "failed to get clock gpio\n"); in fsi_master_gpio_probe()
793 master->gpio_clk = gpio; in fsi_master_gpio_probe()
795 gpio = devm_gpiod_get(&pdev->dev, "data", 0); in fsi_master_gpio_probe()
797 dev_err(&pdev->dev, "failed to get data gpio\n"); in fsi_master_gpio_probe()
801 master->gpio_data = gpio; in fsi_master_gpio_probe()
804 gpio = devm_gpiod_get_optional(&pdev->dev, "trans", 0); in fsi_master_gpio_probe()
806 dev_err(&pdev->dev, "failed to get trans gpio\n"); in fsi_master_gpio_probe()
810 master->gpio_trans = gpio; in fsi_master_gpio_probe()
812 gpio = devm_gpiod_get_optional(&pdev->dev, "enable", 0); in fsi_master_gpio_probe()
814 dev_err(&pdev->dev, "failed to get enable gpio\n"); in fsi_master_gpio_probe()
818 master->gpio_enable = gpio; in fsi_master_gpio_probe()
820 gpio = devm_gpiod_get_optional(&pdev->dev, "mux", 0); in fsi_master_gpio_probe()
822 dev_err(&pdev->dev, "failed to get mux gpio\n"); in fsi_master_gpio_probe()
826 master->gpio_mux = gpio; in fsi_master_gpio_probe()
833 master->no_delays = device_property_present(&pdev->dev, "no-gpio-delays"); in fsi_master_gpio_probe()
835 /* Default FSI command delays */ in fsi_master_gpio_probe()
836 master->t_send_delay = FSI_SEND_DELAY_CLOCKS; in fsi_master_gpio_probe()
837 master->t_echo_delay = FSI_ECHO_DELAY_CLOCKS; in fsi_master_gpio_probe()
839 master->master.n_links = 1; in fsi_master_gpio_probe()
840 master->master.flags = FSI_MASTER_FLAG_SWCLOCK; in fsi_master_gpio_probe()
841 master->master.read = fsi_master_gpio_read; in fsi_master_gpio_probe()
842 master->master.write = fsi_master_gpio_write; in fsi_master_gpio_probe()
843 master->master.term = fsi_master_gpio_term; in fsi_master_gpio_probe()
844 master->master.send_break = fsi_master_gpio_break; in fsi_master_gpio_probe()
845 master->master.link_enable = fsi_master_gpio_link_enable; in fsi_master_gpio_probe()
846 master->master.link_config = fsi_master_gpio_link_config; in fsi_master_gpio_probe()
847 platform_set_drvdata(pdev, master); in fsi_master_gpio_probe()
848 mutex_init(&master->cmd_lock); in fsi_master_gpio_probe()
850 fsi_master_gpio_init(master); in fsi_master_gpio_probe()
852 rc = device_create_file(&pdev->dev, &dev_attr_external_mode); in fsi_master_gpio_probe()
856 rc = fsi_master_register(&master->master); in fsi_master_gpio_probe()
858 device_remove_file(&pdev->dev, &dev_attr_external_mode); in fsi_master_gpio_probe()
859 put_device(&master->master.dev); in fsi_master_gpio_probe()
864 kfree(master); in fsi_master_gpio_probe()
872 struct fsi_master_gpio *master = platform_get_drvdata(pdev); in fsi_master_gpio_remove() local
874 device_remove_file(&pdev->dev, &dev_attr_external_mode); in fsi_master_gpio_remove()
876 fsi_master_unregister(&master->master); in fsi_master_gpio_remove()
880 { .compatible = "fsi-master-gpio" },
887 .name = "fsi-master-gpio",
895 MODULE_DESCRIPTION("A FSI master controller, using a simple GPIO bit-banging interface");