Lines Matching +full:adc +full:- +full:dev
1 /*-
50 #include <dev/ofw/openfirm.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
55 #include <dev/evdev/input.h>
56 #include <dev/evdev/evdev.h>
87 static int ti_adc_detach(device_t dev);
94 evdev_push_event(sc->sc_evdev, EV_ABS, ABS_X, sc->sc_x); in ti_adc_ev_report()
95 evdev_push_event(sc->sc_evdev, EV_ABS, ABS_Y, sc->sc_y); in ti_adc_ev_report()
96 evdev_push_event(sc->sc_evdev, EV_KEY, BTN_TOUCH, sc->sc_pen_down); in ti_adc_ev_report()
97 evdev_sync(sc->sc_evdev); in ti_adc_ev_report()
108 if (sc->sc_last_state == 1) in ti_adc_enable()
116 if (sc->sc_tsc_wires > 0) { in ti_adc_enable()
118 switch (sc->sc_tsc_wires) { in ti_adc_enable()
133 /* Enable the ADC. Run thru enabled steps, start the conversions. */ in ti_adc_enable()
136 sc->sc_last_state = 1; in ti_adc_enable()
146 if (sc->sc_last_state == 0) in ti_adc_disable()
152 /* Disable the ADC. */ in ti_adc_disable()
175 sc->sc_last_state = 0; in ti_adc_disable()
187 enabled = sc->sc_tsc_enabled; in ti_adc_setup()
188 for (i = 0; i < sc->sc_adc_nchannels; i++) { in ti_adc_setup()
189 ain = sc->sc_adc_channels[i]; in ti_adc_setup()
194 /* Set the ADC global status. */ in ti_adc_setup()
215 reg = input->stepconfig; in ti_adc_input_setup()
229 val |= input->samples << ADC_STEP_AVG_SHIFT; in ti_adc_input_setup()
235 /* Set the ADC to one-shot mode. */ in ti_adc_input_setup()
249 for (i = 0; i < sc->sc_adc_nchannels; i++) { in ti_adc_reset()
250 ain = sc->sc_adc_channels[i]; in ti_adc_reset()
268 if (error != 0 || req->newptr == NULL) in ti_adc_clockdiv_proc()
272 * The actual written value is the prescaler setting - 1. in ti_adc_clockdiv_proc()
274 * ADC clock to ~2.4Mhz (CLK_M_OSC / 10). in ti_adc_clockdiv_proc()
276 reg--; in ti_adc_clockdiv_proc()
283 /* Disable the ADC. */ in ti_adc_clockdiv_proc()
285 /* Update the ADC prescaler setting. */ in ti_adc_clockdiv_proc()
287 /* Enable the ADC again. */ in ti_adc_clockdiv_proc()
303 sc = input->sc; in ti_adc_enable_proc()
305 enable = input->enable; in ti_adc_enable_proc()
308 if (error != 0 || req->newptr == NULL) in ti_adc_enable_proc()
315 /* Setup the ADC as needed. */ in ti_adc_enable_proc()
316 if (input->enable != enable) { in ti_adc_enable_proc()
317 input->enable = enable; in ti_adc_enable_proc()
319 if (input->enable == 0) in ti_adc_enable_proc()
320 input->value = 0; in ti_adc_enable_proc()
335 sc = input->sc; in ti_adc_open_delay_proc()
338 reg = (int)ADC_READ4(sc, input->stepdelay) & ADC_STEP_OPEN_DELAY; in ti_adc_open_delay_proc()
342 if (error != 0 || req->newptr == NULL) in ti_adc_open_delay_proc()
349 ADC_WRITE4(sc, input->stepdelay, reg & ADC_STEP_OPEN_DELAY); in ti_adc_open_delay_proc()
363 sc = input->sc; in ti_adc_samples_avg_proc()
365 if (input->samples > nitems(ti_adc_samples)) in ti_adc_samples_avg_proc()
366 input->samples = nitems(ti_adc_samples); in ti_adc_samples_avg_proc()
367 samples = ti_adc_samples[input->samples]; in ti_adc_samples_avg_proc()
370 if (error != 0 || req->newptr == NULL) in ti_adc_samples_avg_proc()
374 if (samples != ti_adc_samples[input->samples]) { in ti_adc_samples_avg_proc()
375 input->samples = 0; in ti_adc_samples_avg_proc()
378 input->samples = i; in ti_adc_samples_avg_proc()
379 ti_adc_input_setup(sc, input->input); in ti_adc_samples_avg_proc()
401 if (input->enable == 0) in ti_adc_read_data()
402 input->value = 0; in ti_adc_read_data()
404 input->value = (int32_t)(data & ADC_FIFO_DATA_MSK); in ti_adc_read_data()
416 return -1; in cmp_values()
444 if (sc->sc_coord_readouts > 3) { in ti_adc_tsc_read_data()
446 end = sc->sc_coord_readouts - 1; in ti_adc_tsc_read_data()
447 qsort(data, sc->sc_coord_readouts, in ti_adc_tsc_read_data()
449 qsort(&data[sc->sc_coord_readouts + 2], in ti_adc_tsc_read_data()
450 sc->sc_coord_readouts, in ti_adc_tsc_read_data()
455 end = sc->sc_coord_readouts; in ti_adc_tsc_read_data()
461 y /= (end - start); in ti_adc_tsc_read_data()
463 for (i = sc->sc_coord_readouts + 2 + start; i < sc->sc_coord_readouts + 2 + end; i++) in ti_adc_tsc_read_data()
465 x /= (end - start); in ti_adc_tsc_read_data()
468 device_printf(sc->sc_dev, "touchscreen x: %d, y: %d\n", x, y); in ti_adc_tsc_read_data()
472 if ((sc->sc_x != x) || (sc->sc_y != y)) { in ti_adc_tsc_read_data()
473 sc->sc_x = x; in ti_adc_tsc_read_data()
474 sc->sc_y = y; in ti_adc_tsc_read_data()
511 sc->sc_pen_down = 1; in ti_adc_intr()
521 sc->sc_pen_down = 0; in ti_adc_intr()
556 * Add per-pin sysctl tree/handlers. in ti_adc_sysctl_init()
558 ctx = device_get_sysctl_ctx(sc->sc_dev); in ti_adc_sysctl_init()
559 tree_node = device_get_sysctl_tree(sc->sc_dev); in ti_adc_sysctl_init()
563 ti_adc_clockdiv_proc, "IU", "ADC clock prescaler"); in ti_adc_sysctl_init()
565 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ADC inputs"); in ti_adc_sysctl_init()
568 for (i = 0; i < sc->sc_adc_nchannels; i++) { in ti_adc_sysctl_init()
569 ain = sc->sc_adc_channels[i]; in ti_adc_sysctl_init()
573 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "ADC input"); in ti_adc_sysctl_init()
579 ti_adc_enable_proc, "IU", "Enable ADC input"); in ti_adc_sysctl_init()
583 ti_adc_open_delay_proc, "IU", "ADC open delay"); in ti_adc_sysctl_init()
587 ti_adc_samples_avg_proc, "IU", "ADC samples average"); in ti_adc_sysctl_init()
590 "Converted raw value for the ADC input"); in ti_adc_sysctl_init()
601 for (i = 0; i < sc->sc_adc_nchannels; i++) { in ti_adc_inputs_init()
602 ain = sc->sc_adc_channels[i]; in ti_adc_inputs_init()
604 input->sc = sc; in ti_adc_inputs_init()
605 input->input = ain; in ti_adc_inputs_init()
606 input->value = 0; in ti_adc_inputs_init()
607 input->enable = 0; in ti_adc_inputs_init()
608 input->samples = 0; in ti_adc_inputs_init()
624 ADC_STEP_MODE_HW_ONESHOT | sc->sc_xp_bit; in ti_adc_tsc_init()
625 if (sc->sc_tsc_wires == 4) in ti_adc_tsc_init()
626 stepconfig |= ADC_STEP_INP(sc->sc_yp_inp) | sc->sc_xn_bit; in ti_adc_tsc_init()
627 else if (sc->sc_tsc_wires == 5) in ti_adc_tsc_init()
629 sc->sc_xn_bit | sc->sc_yn_bit | sc->sc_yp_bit; in ti_adc_tsc_init()
630 else if (sc->sc_tsc_wires == 8) in ti_adc_tsc_init()
631 stepconfig |= ADC_STEP_INP(sc->sc_yp_inp) | sc->sc_xn_bit; in ti_adc_tsc_init()
633 start_step = ADC_STEPS - sc->sc_coord_readouts + 1; in ti_adc_tsc_init()
634 end_step = start_step + sc->sc_coord_readouts - 1; in ti_adc_tsc_init()
642 ADC_STEP_MODE_HW_ONESHOT | sc->sc_yn_bit | in ti_adc_tsc_init()
644 if (sc->sc_tsc_wires == 4) in ti_adc_tsc_init()
645 stepconfig |= ADC_STEP_INP(sc->sc_xp_inp) | sc->sc_yp_bit; in ti_adc_tsc_init()
646 else if (sc->sc_tsc_wires == 5) in ti_adc_tsc_init()
648 sc->sc_xp_bit | sc->sc_xn_bit | sc->sc_yp_bit; in ti_adc_tsc_init()
649 else if (sc->sc_tsc_wires == 8) in ti_adc_tsc_init()
650 stepconfig |= ADC_STEP_INP(sc->sc_xp_inp) | sc->sc_yp_bit; in ti_adc_tsc_init()
652 start_step = ADC_STEPS - (sc->sc_coord_readouts*2 + 2) + 1; in ti_adc_tsc_init()
653 end_step = start_step + sc->sc_coord_readouts - 1; in ti_adc_tsc_init()
662 ADC_WRITE4(sc, ADC_TC_CHARGE_DELAY, sc->sc_charge_delay); in ti_adc_tsc_init()
665 start_step = ADC_STEPS - (sc->sc_coord_readouts + 2) + 1; in ti_adc_tsc_init()
667 ADC_STEP_MODE_HW_ONESHOT | sc->sc_yp_bit | in ti_adc_tsc_init()
668 sc->sc_xn_bit | ADC_STEP_INP(sc->sc_xp_inp) | in ti_adc_tsc_init()
673 stepconfig |= ADC_STEP_INP(sc->sc_yn_inp); in ti_adc_tsc_init()
677 ADC_WRITE4(sc, ADC_FIFO1THRESHOLD, (sc->sc_coord_readouts*2 + 2) - 1); in ti_adc_tsc_init()
679 sc->sc_tsc_enabled = 1; in ti_adc_tsc_init()
680 start_step = ADC_STEPS - (sc->sc_coord_readouts*2 + 2) + 1; in ti_adc_tsc_init()
683 sc->sc_tsc_enabled |= (1 << i); in ti_adc_tsc_init()
710 sc->sc_xp_bit = ADC_STEP_XPP_SW; in ti_adc_config_wires()
711 sc->sc_xp_inp = ai; in ti_adc_config_wires()
714 sc->sc_xn_bit = ADC_STEP_XNN_SW; in ti_adc_config_wires()
715 sc->sc_xn_inp = ai; in ti_adc_config_wires()
718 sc->sc_yp_bit = ADC_STEP_YPP_SW; in ti_adc_config_wires()
719 sc->sc_yp_inp = ai; in ti_adc_config_wires()
722 sc->sc_yn_bit = ADC_STEP_YNN_SW; in ti_adc_config_wires()
723 sc->sc_yn_inp = ai; in ti_adc_config_wires()
726 device_printf(sc->sc_dev, "Invalid wire config\n"); in ti_adc_config_wires()
727 return (-1); in ti_adc_config_wires()
734 ti_adc_probe(device_t dev) in ti_adc_probe() argument
737 if (!ofw_bus_is_compatible(dev, "ti,am3359-tscadc")) in ti_adc_probe()
739 device_set_desc(dev, "TI ADC controller"); in ti_adc_probe()
745 ti_adc_attach(device_t dev) in ti_adc_attach() argument
756 sc = device_get_softc(dev); in ti_adc_attach()
757 sc->sc_dev = dev; in ti_adc_attach()
759 node = ofw_bus_get_node(dev); in ti_adc_attach()
761 sc->sc_tsc_wires = 0; in ti_adc_attach()
762 sc->sc_coord_readouts = 1; in ti_adc_attach()
763 sc->sc_x_plate_resistance = 0; in ti_adc_attach()
764 sc->sc_charge_delay = DEFAULT_CHARGE_DELAY; in ti_adc_attach()
769 sc->sc_tsc_wires = cell; in ti_adc_attach()
770 if ((OF_getencprop(child, "ti,coordinate-readouts", &cell, in ti_adc_attach()
772 sc->sc_coord_readouts = cell; in ti_adc_attach()
773 if ((OF_getencprop(child, "ti,x-plate-resistance", &cell, in ti_adc_attach()
775 sc->sc_x_plate_resistance = cell; in ti_adc_attach()
776 if ((OF_getencprop(child, "ti,charge-delay", &cell, in ti_adc_attach()
778 sc->sc_charge_delay = cell; in ti_adc_attach()
780 "ti,wire-config", sizeof(*wire_configs), in ti_adc_attach()
782 if (nwire_configs != sc->sc_tsc_wires) { in ti_adc_attach()
783 device_printf(sc->sc_dev, in ti_adc_attach()
784 "invalid number of ti,wire-config: %d (should be %d)\n", in ti_adc_attach()
785 nwire_configs, sc->sc_tsc_wires); in ti_adc_attach()
795 /* Read "adc" node properties */ in ti_adc_attach()
796 child = ofw_bus_find_child(node, "adc"); in ti_adc_attach()
798 sc->sc_adc_nchannels = OF_getencprop_alloc_multi(child, in ti_adc_attach()
799 "ti,adc-channels", sizeof(*channels), (void **)&channels); in ti_adc_attach()
800 if (sc->sc_adc_nchannels > 0) { in ti_adc_attach()
801 for (i = 0; i < sc->sc_adc_nchannels; i++) in ti_adc_attach()
802 sc->sc_adc_channels[i] = channels[i]; in ti_adc_attach()
808 if (sc->sc_tsc_wires + sc->sc_adc_nchannels > TI_ADC_NPINS) { in ti_adc_attach()
809 device_printf(dev, "total number of channels (%d) is larger than %d\n", in ti_adc_attach()
810 sc->sc_tsc_wires + sc->sc_adc_nchannels, TI_ADC_NPINS); in ti_adc_attach()
815 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in ti_adc_attach()
817 if (!sc->sc_mem_res) { in ti_adc_attach()
818 device_printf(dev, "cannot allocate memory window\n"); in ti_adc_attach()
823 err = ti_sysc_clock_enable(device_get_parent(dev)); in ti_adc_attach()
828 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in ti_adc_attach()
830 if (!sc->sc_irq_res) { in ti_adc_attach()
831 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in ti_adc_attach()
832 device_printf(dev, "cannot allocate interrupt\n"); in ti_adc_attach()
836 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, in ti_adc_attach()
837 NULL, ti_adc_intr, sc, &sc->sc_intrhand) != 0) { in ti_adc_attach()
838 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in ti_adc_attach()
839 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in ti_adc_attach()
840 device_printf(dev, "Unable to setup the irq handler.\n"); in ti_adc_attach()
844 /* Check the ADC revision. */ in ti_adc_attach()
845 rev = ADC_READ4(sc, ti_sysc_get_rev_address_offset_host(device_get_parent(dev))); in ti_adc_attach()
846 device_printf(dev, in ti_adc_attach()
859 * Set the ADC prescaler to 2400 if touchscreen is not enabled in ti_adc_attach()
860 * and to 24 if it is. This sets the ADC clock to ~10Khz and in ti_adc_attach()
863 if (sc->sc_tsc_wires) in ti_adc_attach()
864 ADC_WRITE4(sc, ADC_CLKDIV, 24 - 1); in ti_adc_attach()
866 ADC_WRITE4(sc, ADC_CLKDIV, 2400 - 1); in ti_adc_attach()
880 if (sc->sc_tsc_wires > 0) { in ti_adc_attach()
881 sc->sc_evdev = evdev_alloc(); in ti_adc_attach()
882 evdev_set_name(sc->sc_evdev, device_get_desc(dev)); in ti_adc_attach()
883 evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev)); in ti_adc_attach()
884 evdev_set_id(sc->sc_evdev, BUS_VIRTUAL, 0, 0, 0); in ti_adc_attach()
885 evdev_support_prop(sc->sc_evdev, INPUT_PROP_DIRECT); in ti_adc_attach()
886 evdev_support_event(sc->sc_evdev, EV_SYN); in ti_adc_attach()
887 evdev_support_event(sc->sc_evdev, EV_ABS); in ti_adc_attach()
888 evdev_support_event(sc->sc_evdev, EV_KEY); in ti_adc_attach()
890 evdev_support_abs(sc->sc_evdev, ABS_X, 0, in ti_adc_attach()
892 evdev_support_abs(sc->sc_evdev, ABS_Y, 0, in ti_adc_attach()
895 evdev_support_key(sc->sc_evdev, BTN_TOUCH); in ti_adc_attach()
897 err = evdev_register(sc->sc_evdev); in ti_adc_attach()
899 device_printf(dev, in ti_adc_attach()
901 ti_adc_detach(dev); in ti_adc_attach()
905 sc->sc_pen_down = 0; in ti_adc_attach()
906 sc->sc_x = -1; in ti_adc_attach()
907 sc->sc_y = -1; in ti_adc_attach()
915 ti_adc_detach(device_t dev) in ti_adc_detach() argument
920 error = bus_generic_detach(dev); in ti_adc_detach()
924 sc = device_get_softc(dev); in ti_adc_detach()
926 /* Turn off the ADC. */ in ti_adc_detach()
932 evdev_free(sc->sc_evdev); in ti_adc_detach()
939 if (sc->sc_intrhand) in ti_adc_detach()
940 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); in ti_adc_detach()
941 if (sc->sc_irq_res) in ti_adc_detach()
942 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); in ti_adc_detach()
943 if (sc->sc_mem_res) in ti_adc_detach()
944 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); in ti_adc_detach()