xref: /freebsd/sys/arm/ti/ti_adc.c (revision d9f0ce31900a48d1a2bfc1c8c86f79d1e831451a)
1 /*-
2  * Copyright 2014 Luiz Otavio O Souza <loos@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 
34 #include <sys/kernel.h>
35 #include <sys/limits.h>
36 #include <sys/lock.h>
37 #include <sys/module.h>
38 #include <sys/mutex.h>
39 #include <sys/resource.h>
40 #include <sys/rman.h>
41 #include <sys/sysctl.h>
42 
43 #include <machine/bus.h>
44 
45 #include <dev/ofw/openfirm.h>
46 #include <dev/ofw/ofw_bus.h>
47 #include <dev/ofw/ofw_bus_subr.h>
48 
49 #include <arm/ti/ti_prcm.h>
50 #include <arm/ti/ti_adcreg.h>
51 #include <arm/ti/ti_adcvar.h>
52 
53 /* Define our 8 steps, one for each input channel. */
54 static struct ti_adc_input ti_adc_inputs[TI_ADC_NPINS] = {
55 	{ .stepconfig = ADC_STEPCFG1, .stepdelay = ADC_STEPDLY1 },
56 	{ .stepconfig = ADC_STEPCFG2, .stepdelay = ADC_STEPDLY2 },
57 	{ .stepconfig = ADC_STEPCFG3, .stepdelay = ADC_STEPDLY3 },
58 	{ .stepconfig = ADC_STEPCFG4, .stepdelay = ADC_STEPDLY4 },
59 	{ .stepconfig = ADC_STEPCFG5, .stepdelay = ADC_STEPDLY5 },
60 	{ .stepconfig = ADC_STEPCFG6, .stepdelay = ADC_STEPDLY6 },
61 	{ .stepconfig = ADC_STEPCFG7, .stepdelay = ADC_STEPDLY7 },
62 	{ .stepconfig = ADC_STEPCFG8, .stepdelay = ADC_STEPDLY8 },
63 };
64 
65 static int ti_adc_samples[5] = { 0, 2, 4, 8, 16 };
66 
67 static void
68 ti_adc_enable(struct ti_adc_softc *sc)
69 {
70 
71 	TI_ADC_LOCK_ASSERT(sc);
72 
73 	if (sc->sc_last_state == 1)
74 		return;
75 
76 	/* Enable the FIFO0 threshold and the end of sequence interrupt. */
77 	ADC_WRITE4(sc, ADC_IRQENABLE_SET,
78 	    ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ);
79 
80 	/* Enable the ADC.  Run thru enabled steps, start the conversions. */
81 	ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) | ADC_CTRL_ENABLE);
82 
83 	sc->sc_last_state = 1;
84 }
85 
86 static void
87 ti_adc_disable(struct ti_adc_softc *sc)
88 {
89 	int count;
90 	uint32_t data;
91 
92 	TI_ADC_LOCK_ASSERT(sc);
93 
94 	if (sc->sc_last_state == 0)
95 		return;
96 
97 	/* Disable all the enabled steps. */
98 	ADC_WRITE4(sc, ADC_STEPENABLE, 0);
99 
100 	/* Disable the ADC. */
101 	ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) & ~ADC_CTRL_ENABLE);
102 
103 	/* Disable the FIFO0 threshold and the end of sequence interrupt. */
104 	ADC_WRITE4(sc, ADC_IRQENABLE_CLR,
105 	    ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ);
106 
107 	/* ACK any pending interrupt. */
108 	ADC_WRITE4(sc, ADC_IRQSTATUS, ADC_READ4(sc, ADC_IRQSTATUS));
109 
110 	/* Drain the FIFO data. */
111 	count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
112 	while (count > 0) {
113 		data = ADC_READ4(sc, ADC_FIFO0DATA);
114 		count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
115 	}
116 
117 	sc->sc_last_state = 0;
118 }
119 
120 static int
121 ti_adc_setup(struct ti_adc_softc *sc)
122 {
123 	int ain;
124 	uint32_t enabled;
125 
126 	TI_ADC_LOCK_ASSERT(sc);
127 
128 	/* Check for enabled inputs. */
129 	enabled = 0;
130 	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
131 		if (ti_adc_inputs[ain].enable)
132 			enabled |= (1U << (ain + 1));
133 	}
134 
135 	/* Set the ADC global status. */
136 	if (enabled != 0) {
137 		ti_adc_enable(sc);
138 		/* Update the enabled steps. */
139 		if (enabled != ADC_READ4(sc, ADC_STEPENABLE))
140 			ADC_WRITE4(sc, ADC_STEPENABLE, enabled);
141 	} else
142 		ti_adc_disable(sc);
143 
144 	return (0);
145 }
146 
147 static void
148 ti_adc_input_setup(struct ti_adc_softc *sc, int32_t ain)
149 {
150 	struct ti_adc_input *input;
151 	uint32_t reg, val;
152 
153 	TI_ADC_LOCK_ASSERT(sc);
154 
155 	input = &ti_adc_inputs[ain];
156 	reg = input->stepconfig;
157 	val = ADC_READ4(sc, reg);
158 
159 	/* Set single ended operation. */
160 	val &= ~ADC_STEP_DIFF_CNTRL;
161 
162 	/* Set the negative voltage reference. */
163 	val &= ~ADC_STEP_RFM_MSK;
164 
165 	/* Set the positive voltage reference. */
166 	val &= ~ADC_STEP_RFP_MSK;
167 
168 	/* Set the samples average. */
169 	val &= ~ADC_STEP_AVG_MSK;
170 	val |= input->samples << ADC_STEP_AVG_SHIFT;
171 
172 	/* Select the desired input. */
173 	val &= ~ADC_STEP_INP_MSK;
174 	val |= ain << ADC_STEP_INP_SHIFT;
175 
176 	/* Set the ADC to one-shot mode. */
177 	val &= ~ADC_STEP_MODE_MSK;
178 
179 	ADC_WRITE4(sc, reg, val);
180 }
181 
182 static void
183 ti_adc_reset(struct ti_adc_softc *sc)
184 {
185 	int ain;
186 
187 	TI_ADC_LOCK_ASSERT(sc);
188 
189 	/* Disable all the inputs. */
190 	for (ain = 0; ain < TI_ADC_NPINS; ain++)
191 		ti_adc_inputs[ain].enable = 0;
192 }
193 
194 static int
195 ti_adc_clockdiv_proc(SYSCTL_HANDLER_ARGS)
196 {
197 	int error, reg;
198 	struct ti_adc_softc *sc;
199 
200 	sc = (struct ti_adc_softc *)arg1;
201 
202 	TI_ADC_LOCK(sc);
203 	reg = (int)ADC_READ4(sc, ADC_CLKDIV) + 1;
204 	TI_ADC_UNLOCK(sc);
205 
206 	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
207 	if (error != 0 || req->newptr == NULL)
208 		return (error);
209 
210 	/*
211 	 * The actual written value is the prescaler setting - 1.
212 	 * Enforce a minimum value of 10 (i.e. 9) which limits the maximum
213 	 * ADC clock to ~2.4Mhz (CLK_M_OSC / 10).
214 	 */
215 	reg--;
216 	if (reg < 9)
217 		reg = 9;
218 	if (reg > USHRT_MAX)
219 		reg = USHRT_MAX;
220 
221 	TI_ADC_LOCK(sc);
222 	/* Disable the ADC. */
223 	ti_adc_disable(sc);
224 	/* Update the ADC prescaler setting. */
225 	ADC_WRITE4(sc, ADC_CLKDIV, reg);
226 	/* Enable the ADC again. */
227 	ti_adc_setup(sc);
228 	TI_ADC_UNLOCK(sc);
229 
230 	return (0);
231 }
232 
233 static int
234 ti_adc_enable_proc(SYSCTL_HANDLER_ARGS)
235 {
236 	int error;
237 	int32_t enable;
238 	struct ti_adc_softc *sc;
239 	struct ti_adc_input *input;
240 
241 	input = (struct ti_adc_input *)arg1;
242 	sc = input->sc;
243 
244 	enable = input->enable;
245 	error = sysctl_handle_int(oidp, &enable, sizeof(enable),
246 	    req);
247 	if (error != 0 || req->newptr == NULL)
248 		return (error);
249 
250 	if (enable)
251 		enable = 1;
252 
253 	TI_ADC_LOCK(sc);
254 	/* Setup the ADC as needed. */
255 	if (input->enable != enable) {
256 		input->enable = enable;
257 		ti_adc_setup(sc);
258 		if (input->enable == 0)
259 			input->value = 0;
260 	}
261 	TI_ADC_UNLOCK(sc);
262 
263 	return (0);
264 }
265 
266 static int
267 ti_adc_open_delay_proc(SYSCTL_HANDLER_ARGS)
268 {
269 	int error, reg;
270 	struct ti_adc_softc *sc;
271 	struct ti_adc_input *input;
272 
273 	input = (struct ti_adc_input *)arg1;
274 	sc = input->sc;
275 
276 	TI_ADC_LOCK(sc);
277 	reg = (int)ADC_READ4(sc, input->stepdelay) & ADC_STEP_OPEN_DELAY;
278 	TI_ADC_UNLOCK(sc);
279 
280 	error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
281 	if (error != 0 || req->newptr == NULL)
282 		return (error);
283 
284 	if (reg < 0)
285 		reg = 0;
286 
287 	TI_ADC_LOCK(sc);
288 	ADC_WRITE4(sc, input->stepdelay, reg & ADC_STEP_OPEN_DELAY);
289 	TI_ADC_UNLOCK(sc);
290 
291 	return (0);
292 }
293 
294 static int
295 ti_adc_samples_avg_proc(SYSCTL_HANDLER_ARGS)
296 {
297 	int error, samples, i;
298 	struct ti_adc_softc *sc;
299 	struct ti_adc_input *input;
300 
301 	input = (struct ti_adc_input *)arg1;
302 	sc = input->sc;
303 
304 	if (input->samples > nitems(ti_adc_samples))
305 		input->samples = nitems(ti_adc_samples);
306 	samples = ti_adc_samples[input->samples];
307 
308 	error = sysctl_handle_int(oidp, &samples, 0, req);
309 	if (error != 0 || req->newptr == NULL)
310 		return (error);
311 
312 	TI_ADC_LOCK(sc);
313 	if (samples != ti_adc_samples[input->samples]) {
314 		input->samples = 0;
315 		for (i = 0; i < nitems(ti_adc_samples); i++)
316 			if (samples >= ti_adc_samples[i])
317 				input->samples = i;
318 		ti_adc_input_setup(sc, input->input);
319 	}
320 	TI_ADC_UNLOCK(sc);
321 
322 	return (error);
323 }
324 
325 static void
326 ti_adc_read_data(struct ti_adc_softc *sc)
327 {
328 	int count, ain;
329 	struct ti_adc_input *input;
330 	uint32_t data;
331 
332 	TI_ADC_LOCK_ASSERT(sc);
333 
334 	/* Read the available data. */
335 	count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
336 	while (count > 0) {
337 		data = ADC_READ4(sc, ADC_FIFO0DATA);
338 		ain = (data & ADC_FIFO_STEP_ID_MSK) >> ADC_FIFO_STEP_ID_SHIFT;
339 		input = &ti_adc_inputs[ain];
340 		if (input->enable == 0)
341 			input->value = 0;
342 		else
343 			input->value = (int32_t)(data & ADC_FIFO_DATA_MSK);
344 		count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK;
345 	}
346 }
347 
348 static void
349 ti_adc_intr(void *arg)
350 {
351 	struct ti_adc_softc *sc;
352 	uint32_t status;
353 
354 	sc = (struct ti_adc_softc *)arg;
355 
356 	status = ADC_READ4(sc, ADC_IRQSTATUS);
357 	if (status == 0)
358 		return;
359 	if (status & ~(ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ))
360 		device_printf(sc->sc_dev, "stray interrupt: %#x\n", status);
361 
362 	TI_ADC_LOCK(sc);
363 	/* ACK the interrupt. */
364 	ADC_WRITE4(sc, ADC_IRQSTATUS, status);
365 
366 	/* Read the available data. */
367 	if (status & ADC_IRQ_FIFO0_THRES)
368 		ti_adc_read_data(sc);
369 
370 	/* Start the next conversion ? */
371 	if (status & ADC_IRQ_END_OF_SEQ)
372 		ti_adc_setup(sc);
373 	TI_ADC_UNLOCK(sc);
374 }
375 
376 static void
377 ti_adc_sysctl_init(struct ti_adc_softc *sc)
378 {
379 	char pinbuf[3];
380 	struct sysctl_ctx_list *ctx;
381 	struct sysctl_oid *tree_node, *inp_node, *inpN_node;
382 	struct sysctl_oid_list *tree, *inp_tree, *inpN_tree;
383 	int ain;
384 
385 	/*
386 	 * Add per-pin sysctl tree/handlers.
387 	 */
388 	ctx = device_get_sysctl_ctx(sc->sc_dev);
389 	tree_node = device_get_sysctl_tree(sc->sc_dev);
390 	tree = SYSCTL_CHILDREN(tree_node);
391 	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clockdiv",
392 	    CTLFLAG_RW | CTLTYPE_UINT,  sc, 0,
393 	    ti_adc_clockdiv_proc, "IU", "ADC clock prescaler");
394 	inp_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "ain",
395 	    CTLFLAG_RD, NULL, "ADC inputs");
396 	inp_tree = SYSCTL_CHILDREN(inp_node);
397 
398 	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
399 
400 		snprintf(pinbuf, sizeof(pinbuf), "%d", ain);
401 		inpN_node = SYSCTL_ADD_NODE(ctx, inp_tree, OID_AUTO, pinbuf,
402 		    CTLFLAG_RD, NULL, "ADC input");
403 		inpN_tree = SYSCTL_CHILDREN(inpN_node);
404 
405 		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "enable",
406 		    CTLFLAG_RW | CTLTYPE_UINT, &ti_adc_inputs[ain], 0,
407 		    ti_adc_enable_proc, "IU", "Enable ADC input");
408 		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "open_delay",
409 		    CTLFLAG_RW | CTLTYPE_UINT,  &ti_adc_inputs[ain], 0,
410 		    ti_adc_open_delay_proc, "IU", "ADC open delay");
411 		SYSCTL_ADD_PROC(ctx, inpN_tree, OID_AUTO, "samples_avg",
412 		    CTLFLAG_RW | CTLTYPE_UINT,  &ti_adc_inputs[ain], 0,
413 		    ti_adc_samples_avg_proc, "IU", "ADC samples average");
414 		SYSCTL_ADD_INT(ctx, inpN_tree, OID_AUTO, "input",
415 		    CTLFLAG_RD, &ti_adc_inputs[ain].value, 0,
416 		    "Converted raw value for the ADC input");
417 	}
418 }
419 
420 static void
421 ti_adc_inputs_init(struct ti_adc_softc *sc)
422 {
423 	int ain;
424 	struct ti_adc_input *input;
425 
426 	TI_ADC_LOCK(sc);
427 	for (ain = 0; ain < TI_ADC_NPINS; ain++) {
428 		input = &ti_adc_inputs[ain];
429 		input->sc = sc;
430 		input->input = ain;
431 		input->value = 0;
432 		input->enable = 0;
433 		input->samples = 0;
434 		ti_adc_input_setup(sc, ain);
435 	}
436 	TI_ADC_UNLOCK(sc);
437 }
438 
439 static void
440 ti_adc_idlestep_init(struct ti_adc_softc *sc)
441 {
442 	uint32_t val;
443 
444 	val = ADC_READ4(sc, ADC_IDLECONFIG);
445 
446 	/* Set single ended operation. */
447 	val &= ~ADC_STEP_DIFF_CNTRL;
448 
449 	/* Set the negative voltage reference. */
450 	val &= ~ADC_STEP_RFM_MSK;
451 
452 	/* Set the positive voltage reference. */
453 	val &= ~ADC_STEP_RFP_MSK;
454 
455 	/* Connect the input to VREFN. */
456 	val &= ~ADC_STEP_INP_MSK;
457 	val |= ADC_STEP_IN_VREFN << ADC_STEP_INP_SHIFT;
458 
459 	ADC_WRITE4(sc, ADC_IDLECONFIG, val);
460 }
461 
462 static int
463 ti_adc_probe(device_t dev)
464 {
465 
466 	if (!ofw_bus_is_compatible(dev, "ti,am3359-tscadc"))
467 		return (ENXIO);
468 	device_set_desc(dev, "TI ADC controller");
469 
470 	return (BUS_PROBE_DEFAULT);
471 }
472 
473 static int
474 ti_adc_attach(device_t dev)
475 {
476 	int err, rid;
477 	struct ti_adc_softc *sc;
478 	uint32_t reg, rev;
479 
480 	sc = device_get_softc(dev);
481 	sc->sc_dev = dev;
482 
483 	/* Activate the ADC_TSC module. */
484 	err = ti_prcm_clk_enable(TSC_ADC_CLK);
485 	if (err)
486 		return (err);
487 
488 	rid = 0;
489 	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
490 	    RF_ACTIVE);
491 	if (!sc->sc_mem_res) {
492 		device_printf(dev, "cannot allocate memory window\n");
493 		return (ENXIO);
494 	}
495 
496 	rid = 0;
497 	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
498 	    RF_ACTIVE);
499 	if (!sc->sc_irq_res) {
500 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
501 		device_printf(dev, "cannot allocate interrupt\n");
502 		return (ENXIO);
503 	}
504 
505 	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
506 	    NULL, ti_adc_intr, sc, &sc->sc_intrhand) != 0) {
507 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
508 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
509 		device_printf(dev, "Unable to setup the irq handler.\n");
510 		return (ENXIO);
511 	}
512 
513 	/* Check the ADC revision. */
514 	rev = ADC_READ4(sc, ADC_REVISION);
515 	device_printf(dev,
516 	    "scheme: %#x func: %#x rtl: %d rev: %d.%d custom rev: %d\n",
517 	    (rev & ADC_REV_SCHEME_MSK) >> ADC_REV_SCHEME_SHIFT,
518 	    (rev & ADC_REV_FUNC_MSK) >> ADC_REV_FUNC_SHIFT,
519 	    (rev & ADC_REV_RTL_MSK) >> ADC_REV_RTL_SHIFT,
520 	    (rev & ADC_REV_MAJOR_MSK) >> ADC_REV_MAJOR_SHIFT,
521 	    rev & ADC_REV_MINOR_MSK,
522 	    (rev & ADC_REV_CUSTOM_MSK) >> ADC_REV_CUSTOM_SHIFT);
523 
524 	/*
525 	 * Disable the step write protect and make it store the step ID for
526 	 * the captured data on FIFO.
527 	 */
528 	reg = ADC_READ4(sc, ADC_CTRL);
529 	ADC_WRITE4(sc, ADC_CTRL, reg | ADC_CTRL_STEP_WP | ADC_CTRL_STEP_ID);
530 
531 	/*
532 	 * Set the ADC prescaler to 2400 (yes, the actual value written here
533 	 * is 2400 - 1).
534 	 * This sets the ADC clock to ~10Khz (CLK_M_OSC / 2400).
535 	 */
536 	ADC_WRITE4(sc, ADC_CLKDIV, 2399);
537 
538 	TI_ADC_LOCK_INIT(sc);
539 
540 	ti_adc_idlestep_init(sc);
541 	ti_adc_inputs_init(sc);
542 	ti_adc_sysctl_init(sc);
543 
544 	return (0);
545 }
546 
547 static int
548 ti_adc_detach(device_t dev)
549 {
550 	struct ti_adc_softc *sc;
551 
552 	sc = device_get_softc(dev);
553 
554 	/* Turn off the ADC. */
555 	TI_ADC_LOCK(sc);
556 	ti_adc_reset(sc);
557 	ti_adc_setup(sc);
558 	TI_ADC_UNLOCK(sc);
559 
560 	TI_ADC_LOCK_DESTROY(sc);
561 
562 	if (sc->sc_intrhand)
563 		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
564 	if (sc->sc_irq_res)
565 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
566 	if (sc->sc_mem_res)
567 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
568 
569 	return (bus_generic_detach(dev));
570 }
571 
572 static device_method_t ti_adc_methods[] = {
573 	DEVMETHOD(device_probe,		ti_adc_probe),
574 	DEVMETHOD(device_attach,	ti_adc_attach),
575 	DEVMETHOD(device_detach,	ti_adc_detach),
576 
577 	DEVMETHOD_END
578 };
579 
580 static driver_t ti_adc_driver = {
581 	"ti_adc",
582 	ti_adc_methods,
583 	sizeof(struct ti_adc_softc),
584 };
585 
586 static devclass_t ti_adc_devclass;
587 
588 DRIVER_MODULE(ti_adc, simplebus, ti_adc_driver, ti_adc_devclass, 0, 0);
589 MODULE_VERSION(ti_adc, 1);
590 MODULE_DEPEND(ti_adc, simplebus, 1, 1, 1);
591