Lines Matching +full:poll +full:- +full:retry +full:- +full:count

1 // SPDX-License-Identifier: GPL-2.0-only
3 * A FSI master controller, using a simple GPIO bit-banging interface
18 #include "fsi-master.h"
49 static void clock_toggle(struct fsi_master_gpio *master, int count) in clock_toggle() argument
53 for (i = 0; i < count; i++) { in clock_toggle()
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()
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()
84 gpiod_set_value(master->gpio_data, value); in sda_out()
89 gpiod_direction_input(master->gpio_data); in set_sda_input()
90 gpiod_set_value(master->gpio_trans, 0); in set_sda_input()
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()
103 clock_toggle(master, count); in clock_zeros()
108 clock_zeros(master, master->t_echo_delay); in echo_delay()
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()
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()
151 for (bit = 0; bit < cmd->bits; bit++) { in serial_out()
152 next_bit = (msg & sda_mask) >> (cmd->bits - 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()
189 return master->last_addr == (((id & 0x3) << 21) | (addr & ~0x3)); in check_same_address()
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()
226 master->last_addr = LAST_ADDR_INVALID; in last_address_update()
228 master->last_addr = ((id & 0x3) << 21) | (addr & ~0x3); in last_address_update()
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()
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
354 dev_dbg(master->dev, in read_one_response()
357 return -ETIMEDOUT; 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()
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()
433 retry: 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()
448 "CRC error retry %d\n", crc_err_retries); in poll_for_response()
456 goto retry; 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()
487 goto retry; in poll_for_response()
489 dev_warn(master->dev, 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()
505 rc = -EAGAIN; in poll_for_response()
517 clock_zeros(master, master->t_send_delay); in poll_for_response()
528 if (master->external_mode) in send_request()
529 return -EBUSY; in send_request()
542 int rc = -EAGAIN, retries = 0; 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()
554 /* Pace it a bit before retry */ in fsi_master_gpio_xfer()
569 return -ENODEV; in fsi_master_gpio_read()
571 mutex_lock(&master->cmd_lock); in fsi_master_gpio_read()
575 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_read()
588 return -ENODEV; in fsi_master_gpio_write()
590 mutex_lock(&master->cmd_lock); in fsi_master_gpio_write()
594 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_write()
607 return -ENODEV; in fsi_master_gpio_term()
609 mutex_lock(&master->cmd_lock); in fsi_master_gpio_term()
613 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_term()
624 return -ENODEV; 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()
648 mutex_unlock(&master->cmd_lock); in fsi_master_gpio_break()
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()
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()
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()
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()
721 return snprintf(buf, PAGE_SIZE - 1, "%u\n", in external_mode_show()
722 master->external_mode ? 1 : 0); in external_mode_show()
726 struct device_attribute *attr, const char *buf, size_t count) in external_mode_store() argument
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()
743 return count; in external_mode_store()
746 master->external_mode = external_mode; in external_mode_store()
747 if (master->external_mode) in external_mode_store()
752 mutex_unlock(&master->cmd_lock); in external_mode_store()
754 fsi_master_rescan(&master->master); in external_mode_store()
756 return count; in external_mode_store()
766 of_node_put(dev_of_node(master->dev)); in fsi_master_gpio_release()
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()
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()
848 mutex_init(&master->cmd_lock); 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()
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()
882 { .compatible = "fsi-master-gpio" },
888 .name = "fsi-master-gpio",