Lines Matching +full:i2c +full:- +full:int +full:- +full:falling

38  * Intel fourth generation mobile cpus integrated I2C device.
75 #define DO_POLL(sc) (cold || kdb_active || SCHEDULER_STOPPED() || sc->poll)
78 * tLOW, tHIGH periods of the SCL clock and maximal falling time of both
79 * lines are taken from I2C specifications.
137 static int ig4iic_set_config(ig4iic_softc_t *sc, bool reset);
141 static int ig4_dump;
147 * 0 - Try read clock registers from ACPI and fallback to p.1.
148 * 1 - Calculate values based on controller type (IC clock rate).
149 * 2 - Use values inherited from DragonflyBSD driver (old behavior).
150 * 3 - Keep clock registers intact.
152 static int ig4_timings;
157 * Low-level inline support functions
162 bus_write_4(sc->regs_res, reg, value); in reg_write()
163 bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_WRITE); in reg_write()
171 bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_READ); in reg_read()
172 value = bus_read_4(sc->regs_res, reg); in reg_read()
179 if (sc->intr_mask != val) { in ig4iic_set_intr_mask()
181 sc->intr_mask = val; in ig4iic_set_intr_mask()
185 static int
200 /* User-requested abort. Not really a error */ in intrstat2iic()
238 static int
241 int retry; in set_controller()
242 int error; in set_controller()
256 for (retry = 100; retry > 0; --retry) { in set_controller()
270 static int
274 int error; in wait_intr()
275 int txlvl = -1; in wait_intr()
313 mtx_lock_spin(&sc->io_lock); in wait_intr()
315 msleep_spin(sc, &sc->io_lock, "i2cwait", in wait_intr()
318 mtx_unlock_spin(&sc->io_lock); in wait_intr()
333 * This operation does not issue anything to the I2C bus but sets
344 if (sc->slave_valid && sc->last_slave == slave && in set_slave_addr()
345 sc->use_10bit == use_10bit) { in set_slave_addr()
348 sc->use_10bit = use_10bit; in set_slave_addr()
362 if (sc->use_10bit) { in set_slave_addr()
369 sc->slave_valid = true; in set_slave_addr()
370 sc->last_slave = slave; in set_slave_addr()
376 static int
384 * and I2C bus STOP condition. in ig4iic_xfer_start()
403 static int
406 int error; in ig4iic_xfer_abort()
421 * Amount of unread data before next burst to get better I2C bus utilization.
423 * Intel-recommended value is 16 for DMA transfers with 64-byte depth FIFOs.
427 static int
432 int requested = 0; in ig4iic_read()
433 int received = 0; in ig4iic_read()
434 int burst, target, lowat = 0; in ig4iic_read()
435 int error; in ig4iic_read()
442 burst = sc->cfg.txfifo_depth - in ig4iic_read()
449 burst = sc->cfg.txfifo_depth - in ig4iic_read()
453 burst = MIN(burst, sc->cfg.rxfifo_depth - in ig4iic_read()
454 (requested - received)); in ig4iic_read()
455 target = MIN(requested + burst, (int)len); in ig4iic_read()
460 if (stop && requested == len - 1) in ig4iic_read()
467 if (requested != len && requested - received > IG4_FIFO_LOWAT) in ig4iic_read()
470 while (received < requested - lowat) { in ig4iic_read()
471 burst = MIN(requested - received, in ig4iic_read()
474 while (burst--) in ig4iic_read()
479 requested - received - lowat - 1); in ig4iic_read()
490 static int
495 int sent = 0; in ig4iic_write()
496 int burst, target; in ig4iic_write()
497 int error, lowat; in ig4iic_write()
503 burst = sc->cfg.txfifo_depth - in ig4iic_write()
505 target = MIN(sent + burst, (int)len); in ig4iic_write()
510 if (stop && sent == len - 1) in ig4iic_write()
516 if (len - sent <= sc->cfg.txfifo_depth) in ig4iic_write()
517 lowat = sc->cfg.txfifo_depth - (len - sent); in ig4iic_write()
530 int
536 int error; in ig4iic_transfer()
537 int unit; in ig4iic_transfer()
543 * The hardware interface imposes limits on allowed I2C messages. in ig4iic_transfer()
566 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) { in ig4iic_transfer()
577 (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) { in ig4iic_transfer()
581 if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 && in ig4iic_transfer()
582 msgs[i].slave != msgs[i - 1].slave) { in ig4iic_transfer()
588 (msgs[i - 1].flags & IIC_M_RD)) { in ig4iic_transfer()
602 allocated = sx_xlocked(&sc->call_lock) != 0; in ig4iic_transfer()
604 sx_xlock(&sc->call_lock); in ig4iic_transfer()
606 /* Debugging - dump registers. */ in ig4iic_transfer()
627 if (!sc->slave_valid || in ig4iic_transfer()
628 (msgs[i].slave >> 1) != sc->last_slave) { in ig4iic_transfer()
647 /* Wait for error or stop condition occurred on the I2C bus */ in ig4iic_transfer()
662 device_printf(sc->dev, "Failed to abort " in ig4iic_transfer()
683 sx_unlock(&sc->call_lock); in ig4iic_transfer()
687 int
693 allocated = sx_xlocked(&sc->call_lock) != 0; in ig4iic_reset()
695 sx_xlock(&sc->call_lock); in ig4iic_reset()
699 *oldaddr = sc->last_slave << 1; in ig4iic_reset()
702 sc->slave_valid = false; in ig4iic_reset()
705 sx_unlock(&sc->call_lock); in ig4iic_reset()
709 int
710 ig4iic_callback(device_t dev, int index, caddr_t data) in ig4iic_callback()
713 int error = 0; in ig4iic_callback()
714 int how; in ig4iic_callback()
719 how = *(int *)data; in ig4iic_callback()
721 if (sx_try_xlock(&sc->call_lock) == 0) in ig4iic_callback()
724 sc->poll = true; in ig4iic_callback()
726 sx_xlock(&sc->call_lock); in ig4iic_callback()
730 sc->poll = false; in ig4iic_callback()
731 sx_unlock(&sc->call_lock); in ig4iic_callback()
746 * Precise equations take signal's falling, rising and spike suppression
752 static int
753 ig4iic_clk_params(const struct ig4_hw *hw, int speed, in ig4iic_clk_params()
777 /* Use slowest falling time defaults to be on the safe side */ in ig4iic_clk_params()
778 sda_fall_time = hw->sda_fall_time == 0 ? tf_max : hw->sda_fall_time; in ig4iic_clk_params()
780 ((hw->ic_clock_rate * (thigh + sda_fall_time) + 500) / 1000 - 3); in ig4iic_clk_params()
782 scl_fall_time = hw->scl_fall_time == 0 ? tf_max : hw->scl_fall_time; in ig4iic_clk_params()
784 ((hw->ic_clock_rate * (tlow + scl_fall_time) + 500) / 1000 - 1); in ig4iic_clk_params()
790 if (hw->sda_hold_time != 0) in ig4iic_clk_params()
792 ((hw->ic_clock_rate * hw->sda_hold_time + 500) / 1000); in ig4iic_clk_params()
815 if (obj->Type == ACPI_TYPE_PACKAGE && obj->Package.Count == 3) { in ig4iic_acpi_params()
816 elems = obj->Package.Elements; in ig4iic_acpi_params()
838 sc->cfg.version = reg_read(sc, IG4_REG_COMP_VER); in ig4iic_get_config()
839 sc->cfg.bus_speed = reg_read(sc, IG4_REG_CTL) & IG4_CTL_SPEED_MASK; in ig4iic_get_config()
840 sc->cfg.ss_scl_hcnt = in ig4iic_get_config()
842 sc->cfg.ss_scl_lcnt = in ig4iic_get_config()
844 sc->cfg.fs_scl_hcnt = in ig4iic_get_config()
846 sc->cfg.fs_scl_lcnt = in ig4iic_get_config()
848 sc->cfg.ss_sda_hold = sc->cfg.fs_sda_hold = in ig4iic_get_config()
851 if (sc->cfg.bus_speed != IG4_CTL_SPEED_STD) in ig4iic_get_config()
852 sc->cfg.bus_speed = IG4_CTL_SPEED_FAST; in ig4iic_get_config()
855 if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { in ig4iic_get_config()
858 sc->cfg.txfifo_depth = IG4_PARAM1_TXFIFO_DEPTH(v); in ig4iic_get_config()
860 sc->cfg.rxfifo_depth = IG4_PARAM1_RXFIFO_DEPTH(v); in ig4iic_get_config()
863 /* Override hardware config with IC_clock-based counter values */ in ig4iic_get_config()
864 if (ig4_timings < 2 && sc->version < nitems(ig4iic_hw)) { in ig4iic_get_config()
865 hw = &ig4iic_hw[sc->version]; in ig4iic_get_config()
866 sc->cfg.bus_speed = IG4_CTL_SPEED_FAST; in ig4iic_get_config()
867 ig4iic_clk_params(hw, IG4_CTL_SPEED_STD, &sc->cfg.ss_scl_hcnt, in ig4iic_get_config()
868 &sc->cfg.ss_scl_lcnt, &sc->cfg.ss_sda_hold); in ig4iic_get_config()
869 ig4iic_clk_params(hw, IG4_CTL_SPEED_FAST, &sc->cfg.fs_scl_hcnt, in ig4iic_get_config()
870 &sc->cfg.fs_scl_lcnt, &sc->cfg.fs_sda_hold); in ig4iic_get_config()
871 if (hw->txfifo_depth != 0) in ig4iic_get_config()
872 sc->cfg.txfifo_depth = hw->txfifo_depth; in ig4iic_get_config()
873 if (hw->rxfifo_depth != 0) in ig4iic_get_config()
874 sc->cfg.rxfifo_depth = hw->rxfifo_depth; in ig4iic_get_config()
884 sc->cfg.bus_speed = IG4_CTL_SPEED_STD; in ig4iic_get_config()
885 sc->cfg.ss_scl_hcnt = sc->cfg.fs_scl_hcnt = 100; in ig4iic_get_config()
886 sc->cfg.ss_scl_lcnt = sc->cfg.fs_scl_lcnt = 125; in ig4iic_get_config()
887 if (sc->version == IG4_SKYLAKE) in ig4iic_get_config()
888 sc->cfg.ss_sda_hold = sc->cfg.fs_sda_hold = 28; in ig4iic_get_config()
893 if (ig4_timings == 0 && (handle = acpi_get_handle(sc->dev)) != NULL) { in ig4iic_get_config()
894 ig4iic_acpi_params(handle, "SSCN", &sc->cfg.ss_scl_hcnt, in ig4iic_get_config()
895 &sc->cfg.ss_scl_lcnt, &sc->cfg.ss_sda_hold); in ig4iic_get_config()
896 ig4iic_acpi_params(handle, "FMCN", &sc->cfg.fs_scl_hcnt, in ig4iic_get_config()
897 &sc->cfg.fs_scl_lcnt, &sc->cfg.fs_sda_hold); in ig4iic_get_config()
902 device_printf(sc->dev, "Controller parameters:\n"); in ig4iic_get_config()
904 sc->cfg.bus_speed == IG4_CTL_SPEED_STD ? "Std" : "Fast"); in ig4iic_get_config()
907 sc->cfg.ss_scl_hcnt, sc->cfg.ss_scl_lcnt, in ig4iic_get_config()
908 sc->cfg.ss_sda_hold); in ig4iic_get_config()
910 sc->cfg.fs_scl_hcnt, sc->cfg.fs_scl_lcnt, in ig4iic_get_config()
911 sc->cfg.fs_sda_hold); in ig4iic_get_config()
915 static int
921 if (IG4_HAS_ADDREGS(sc->version) && (v & IG4_RESTORE_REQUIRED)) { in ig4iic_set_config()
928 if ((sc->version == IG4_HASWELL || sc->version == IG4_ATOM) && reset) { in ig4iic_set_config()
931 } else if (IG4_HAS_ADDREGS(sc->version) && reset) { in ig4iic_set_config()
936 if (sc->version == IG4_ATOM) in ig4iic_set_config()
939 if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { in ig4iic_set_config()
946 if (sc->version == IG4_HASWELL && in ig4iic_set_config()
954 if (sc->version == IG4_HASWELL) { in ig4iic_set_config()
957 } else if (IG4_HAS_ADDREGS(sc->version)) { in ig4iic_set_config()
962 if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { in ig4iic_set_config()
969 device_printf(sc->dev, "controller error during attach-1\n"); in ig4iic_set_config()
975 sc->intr_mask = 0; in ig4iic_set_config()
977 reg_write(sc, IG4_REG_SS_SCL_HCNT, sc->cfg.ss_scl_hcnt); in ig4iic_set_config()
978 reg_write(sc, IG4_REG_SS_SCL_LCNT, sc->cfg.ss_scl_lcnt); in ig4iic_set_config()
979 reg_write(sc, IG4_REG_FS_SCL_HCNT, sc->cfg.fs_scl_hcnt); in ig4iic_set_config()
980 reg_write(sc, IG4_REG_FS_SCL_LCNT, sc->cfg.fs_scl_lcnt); in ig4iic_set_config()
982 (sc->cfg.bus_speed & IG4_CTL_SPEED_MASK) == IG4_CTL_SPEED_STD ? in ig4iic_set_config()
983 sc->cfg.ss_sda_hold : sc->cfg.fs_sda_hold); in ig4iic_set_config()
992 (sc->cfg.bus_speed & IG4_CTL_SPEED_MASK)); in ig4iic_set_config()
995 sc->slave_valid = false; in ig4iic_set_config()
1010 if (sc->cfg.txfifo_depth == 0) { in ig4iic_get_fifo()
1013 sc->cfg.txfifo_depth = in ig4iic_get_fifo()
1017 if (sc->cfg.rxfifo_depth == 0) { in ig4iic_get_fifo()
1020 sc->cfg.rxfifo_depth = in ig4iic_get_fifo()
1026 sc->cfg.rxfifo_depth, sc->cfg.txfifo_depth); in ig4iic_get_fifo()
1033 int
1036 int error; in ig4iic_attach()
1038 mtx_init(&sc->io_lock, "IG4 I/O lock", NULL, MTX_SPIN); in ig4iic_attach()
1039 sx_init(&sc->call_lock, "IG4 call lock"); in ig4iic_attach()
1043 error = ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version)); in ig4iic_attach()
1048 sc->iicbus = device_add_child(sc->dev, "iicbus", DEVICE_UNIT_ANY); in ig4iic_attach()
1049 if (sc->iicbus == NULL) { in ig4iic_attach()
1050 device_printf(sc->dev, "iicbus driver not found\n"); in ig4iic_attach()
1056 device_printf(sc->dev, "controller error during attach-2\n"); in ig4iic_attach()
1061 device_printf(sc->dev, "controller error during attach-3\n"); in ig4iic_attach()
1065 error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE, in ig4iic_attach()
1066 ig4iic_intr, NULL, sc, &sc->intr_handle); in ig4iic_attach()
1068 device_printf(sc->dev, in ig4iic_attach()
1072 bus_attach_children(sc->dev); in ig4iic_attach()
1078 int
1081 int error; in ig4iic_detach()
1083 if (device_is_attached(sc->dev)) { in ig4iic_detach()
1084 error = bus_generic_detach(sc->dev); in ig4iic_detach()
1088 if (sc->iicbus) in ig4iic_detach()
1089 device_delete_child(sc->dev, sc->iicbus); in ig4iic_detach()
1090 if (sc->intr_handle) in ig4iic_detach()
1091 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); in ig4iic_detach()
1093 sx_xlock(&sc->call_lock); in ig4iic_detach()
1095 sc->iicbus = NULL; in ig4iic_detach()
1096 sc->intr_handle = NULL; in ig4iic_detach()
1100 sx_xunlock(&sc->call_lock); in ig4iic_detach()
1102 mtx_destroy(&sc->io_lock); in ig4iic_detach()
1103 sx_destroy(&sc->call_lock); in ig4iic_detach()
1108 int
1111 int error; in ig4iic_suspend()
1114 error = bus_generic_suspend(sc->dev); in ig4iic_suspend()
1116 sx_xlock(&sc->call_lock); in ig4iic_suspend()
1118 if (IG4_HAS_ADDREGS(sc->version)) { in ig4iic_suspend()
1124 * Controller can become dysfunctional if I2C lines are pulled in ig4iic_suspend()
1125 * down when suspend procedure turns off power to I2C device. in ig4iic_suspend()
1130 sx_xunlock(&sc->call_lock); in ig4iic_suspend()
1135 int ig4iic_resume(ig4iic_softc_t *sc) in ig4iic_resume()
1137 int error; in ig4iic_resume()
1139 sx_xlock(&sc->call_lock); in ig4iic_resume()
1140 if (ig4iic_set_config(sc, IG4_HAS_ADDREGS(sc->version))) in ig4iic_resume()
1141 device_printf(sc->dev, "controller error during resume\n"); in ig4iic_resume()
1142 sx_xunlock(&sc->call_lock); in ig4iic_resume()
1144 error = bus_generic_resume(sc->dev); in ig4iic_resume()
1152 static int
1156 int retval = FILTER_STRAY; in ig4iic_intr()
1158 mtx_lock_spin(&sc->io_lock); in ig4iic_intr()
1160 if (sc->intr_mask != 0 && reg_read(sc, IG4_REG_INTR_STAT) != 0) { in ig4iic_intr()
1166 mtx_unlock_spin(&sc->io_lock); in ig4iic_intr()
1172 device_printf(sc->dev, " %-23s %08x\n", #reg, reg_read(sc, reg))
1177 device_printf(sc->dev, "ig4iic register dump:\n"); in ig4iic_dump()
1203 if (sc->version == IG4_ATOM) { in ig4iic_dump()
1207 if (sc->version == IG4_HASWELL || sc->version == IG4_ATOM) { in ig4iic_dump()
1210 } else if (sc->version == IG4_SKYLAKE) { in ig4iic_dump()
1213 if (sc->version == IG4_HASWELL) { in ig4iic_dump()
1216 } else if (IG4_HAS_ADDREGS(sc->version)) { in ig4iic_dump()