xref: /netbsd-src/sys/dev/ic/scmd.c (revision a01941bd7fc7c4048bfff19a4983affba2858e17)
1 
2 /*	$NetBSD: scmd.c,v 1.3 2022/10/06 19:38:54 andvar Exp $	*/
3 
4 /*
5  * Copyright (c) 2021 Brad Spencer <brad@anduin.eldar.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: scmd.c,v 1.3 2022/10/06 19:38:54 andvar Exp $");
22 
23 /*
24  * Common driver for the Sparkfun Serial motor controller.
25  * Calls out to specific frontends to move bits.
26 */
27 
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/kernel.h>
31 #include <sys/device.h>
32 #include <sys/module.h>
33 #include <sys/conf.h>
34 #include <sys/sysctl.h>
35 #include <sys/mutex.h>
36 #include <sys/pool.h>
37 #include <sys/kmem.h>
38 
39 #include <dev/i2c/i2cvar.h>
40 #include <dev/spi/spivar.h>
41 #include <dev/ic/scmdreg.h>
42 #include <dev/ic/scmdvar.h>
43 
44 void		scmd_attach(struct scmd_sc *);
45 static void	scmd_wait_restart(struct scmd_sc *, bool);
46 static int	scmd_get_topaddr(struct scmd_sc *);
47 static int 	scmd_verify_sysctl(SYSCTLFN_ARGS);
48 static int	scmd_local_read(struct scmd_sc *, uint8_t, uint8_t *);
49 static int	scmd_remote_read(struct scmd_sc *, int, uint8_t *);
50 static int	scmd_local_write(struct scmd_sc *, uint8_t, uint8_t);
51 static int	scmd_remote_write(struct scmd_sc *, int, uint8_t);
52 
53 #define SCMD_DEBUG
54 #ifdef SCMD_DEBUG
55 #define DPRINTF(s, l, x) \
56     do { \
57 	if (l <= s->sc_scmddebug) \
58 	    printf x; \
59     } while (/*CONSTCOND*/0)
60 #else
61 #define DPRINTF(s, l, x)
62 #endif
63 
64 extern struct cfdriver scmd_cd;
65 
66 static dev_type_open(scmd_open);
67 static dev_type_read(scmd_read);
68 static dev_type_write(scmd_write);
69 static dev_type_close(scmd_close);
70 const struct cdevsw scmd_cdevsw = {
71 	.d_open = scmd_open,
72 	.d_close = scmd_close,
73 	.d_read = scmd_read,
74 	.d_write = scmd_write,
75 	.d_ioctl = noioctl,
76 	.d_stop = nostop,
77 	.d_tty = notty,
78 	.d_poll = nopoll,
79 	.d_mmap = nommap,
80 	.d_kqfilter = nokqfilter,
81 	.d_discard = nodiscard,
82 	.d_flag = D_OTHER
83 };
84 
85 static int
scmd_verify_sysctl(SYSCTLFN_ARGS)86 scmd_verify_sysctl(SYSCTLFN_ARGS)
87 {
88 	int error, t;
89 	struct sysctlnode node;
90 
91 	node = *rnode;
92 	t = *(int *)rnode->sysctl_data;
93 	node.sysctl_data = &t;
94 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
95 	if (error || newp == NULL)
96 		return error;
97 
98 	if (t < 0)
99 		return EINVAL;
100 
101 	*(int *)rnode->sysctl_data = t;
102 
103 	return 0;
104 }
105 
106 static int
scmd_sysctl_init(struct scmd_sc * sc)107 scmd_sysctl_init(struct scmd_sc *sc)
108 {
109 	int error;
110 	const struct sysctlnode *cnode;
111 	int sysctlroot_num;
112 
113 	if ((error = sysctl_createv(&sc->sc_scmdlog, 0, NULL, &cnode,
114 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
115 	    SYSCTL_DESCR("scmd controls"), NULL, 0, NULL, 0, CTL_HW,
116 	    CTL_CREATE, CTL_EOL)) != 0)
117 		return error;
118 
119 	sysctlroot_num = cnode->sysctl_num;
120 
121 #ifdef SCMD_DEBUG
122 	if ((error = sysctl_createv(&sc->sc_scmdlog, 0, NULL, &cnode,
123 	    CTLFLAG_READWRITE, CTLTYPE_INT, "debug",
124 	    SYSCTL_DESCR("Debug level"), scmd_verify_sysctl, 0,
125 	    &sc->sc_scmddebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE,
126 	    CTL_EOL)) != 0)
127 		return error;
128 
129 #endif
130 
131 	return 0;
132 }
133 
134 /* Restarts and re-enumeration of the device is a little strange.
135  * It will take a very long time to complete.  It would be more polite
136  * to use a condvar for this wait, but it was noticed that those may
137  * not work if done too early in boot and will just hang the boot, so
138  * delay is also offered as an option.
139  */
140 static void
scmd_wait_restart(struct scmd_sc * sc,bool usedelay)141 scmd_wait_restart(struct scmd_sc *sc, bool usedelay)
142 {
143 	int error;
144 	uint8_t buf = SCMD_HOLE_VALUE;
145 	int c = 0;
146 
147 	do {
148 		if (usedelay) {
149 			delay(1000000);
150 		} else {
151 			mutex_enter(&sc->sc_condmutex);
152 			cv_timedwait(&sc->sc_condvar, &sc->sc_condmutex,
153 			    mstohz(1000));
154 			mutex_exit(&sc->sc_condmutex);
155 		}
156 
157 		error = (*(sc->sc_func_read_register))(sc, SCMD_REG_STATUS_1, &buf);
158 
159 		DPRINTF(sc, 2, ("%s: Read back status after restart: %02x %d\n",
160 		    device_xname(sc->sc_dev), buf, error));
161 
162 		c++;
163 	} while (c <= 20 && buf != 0x00);
164 }
165 
166 static int
scmd_get_topaddr(struct scmd_sc * sc)167 scmd_get_topaddr(struct scmd_sc *sc)
168 {
169 	uint8_t topaddr;
170 	int error;
171 
172 	error = (*(sc->sc_func_read_register))(sc, SCMD_REG_SLV_TOP_ADDR, &topaddr);
173 
174 	if (error) {
175 		topaddr = 0;
176 	}
177 	return topaddr;
178 }
179 
180 /* Note that this assumes that you can actually access the device.
181  * In at least one case right now, SPI on a Raspberry PI 3, the pins
182  * have not been set up to allow SPI to function, but nothing is
183  * returned as an error either.  We do the best that can be done right
184  * now.
185  */
186 void
scmd_attach(struct scmd_sc * sc)187 scmd_attach(struct scmd_sc *sc)
188 {
189 	int error;
190 
191 	aprint_normal("\n");
192 
193 	if ((error = scmd_sysctl_init(sc)) != 0) {
194 		aprint_error_dev(sc->sc_dev, "Can't setup sysctl tree (%d)\n", error);
195 		goto out;
196 	}
197 
198 	error = (*(sc->sc_func_acquire_bus))(sc);
199 	if (error) {
200 		aprint_error_dev(sc->sc_dev, "Could not acquire iic bus: %d\n",
201 		    error);
202 		goto out;
203 	}
204 
205 	error = (*(sc->sc_func_write_register))(sc, SCMD_REG_CONTROL_1, SCMD_CONTROL_1_RESTART);
206 	if (error != 0)
207 		aprint_error_dev(sc->sc_dev, "Reset failed: %d\n", error);
208 
209 	scmd_wait_restart(sc, true);
210 
211 	sc->sc_topaddr = scmd_get_topaddr(sc);
212 
213 	DPRINTF(sc, 2, ("%s: Top remote module address: %02x\n",
214 	    device_xname(sc->sc_dev), sc->sc_topaddr));
215 
216 	uint8_t fwversion;
217 	uint8_t id;
218 	uint8_t pins;
219 
220 	error = (*(sc->sc_func_read_register))(sc, SCMD_REG_FID, &fwversion);
221 	if (error) {
222 		aprint_error_dev(sc->sc_dev, "Read of FID failed: %d\n",
223 		    error);
224 		goto out;
225 	}
226 
227 	error = (*(sc->sc_func_read_register))(sc, SCMD_REG_ID, &id);
228 	if (error) {
229 		aprint_error_dev(sc->sc_dev, "Read of ID failed: %d\n",
230 		    error);
231 		goto out;
232 	}
233 
234 	error = (*(sc->sc_func_read_register))(sc, SCMD_REG_CONFIG_BITS, &pins);
235 	if (error) {
236 		aprint_error_dev(sc->sc_dev, "Read of CONFIG_BITS failed: %d\n",
237 		    error);
238 		goto out;
239 	}
240 
241 	aprint_normal_dev(sc->sc_dev, "Sparkfun Serial motor controller, "
242 	    "Firmware version: %02x, ID: %02x%s, Jumper pins: %02x\n",
243 	    fwversion, id, (id == SCMD_EXPECTED_ID) ? " (expected ID)" : " (unexpected ID)",
244 	    pins);
245 
246  out:
247 	(*(sc->sc_func_release_bus))(sc);
248 	if (error != 0) {
249 		aprint_error_dev(sc->sc_dev, "Unable to setup device\n");
250 	}
251 
252 	return;
253 }
254 
255 /* This device has the effect of creating a virtual register space of all
256  * of the attached modules.  All you have to do is read and write to anything
257  * in that space and you can hit the main module and all chained slave modules
258  * without having to worry about the view port set up.
259  *
260  * 0x00 - 0x7E -- the first and main module
261  * 0x7F - 0xFD -- the first slaved module
262  * ...etc...
263  *
264  */
265 static int
scmd_open(dev_t dev,int flags,int fmt,struct lwp * l)266 scmd_open(dev_t dev, int flags, int fmt, struct lwp *l)
267 {
268 	struct scmd_sc *sc;
269 
270 	sc = device_lookup_private(&scmd_cd, minor(dev));
271 	if (!sc)
272 		return ENXIO;
273 
274 	if (sc->sc_opened)
275 		return EBUSY;
276 
277 	/* This is a meaningless assignment to keep GCC from
278 	 * complaining.
279 	 */
280 	sc->sc_func_attach = &scmd_attach;
281 
282 	mutex_enter(&sc->sc_mutex);
283 	sc->sc_opened = true;
284 	mutex_exit(&sc->sc_mutex);
285 
286 	return 0;
287 }
288 
289 static int
scmd_maxregister(int topaddr)290 scmd_maxregister(int topaddr)
291 {
292 	if (topaddr >= SCMD_REMOTE_ADDR_LOW &&
293 	    topaddr <= SCMD_REMOTE_ADDR_HIGH) {
294 		int i = (topaddr - SCMD_REMOTE_ADDR_LOW) + 2;
295 		return (SCMD_REG_SIZE * i) - 1;
296 	} else {
297 		return SCMD_LAST_REG;
298 	}
299 }
300 
301 /* Please note that that setting up and using the view port
302  * to get access to SCMD devices that are chained off of the main
303  * device is not atomic.  Hopefully this all happens fast enough
304  * so that nothing can sneak in and mess with the registers.
305  */
306 static int
scmd_set_view_port(struct scmd_sc * sc,int reg)307 scmd_set_view_port(struct scmd_sc *sc, int reg)
308 {
309 	int err;
310 	int loc = reg / SCMD_REG_SIZE;
311 	uint8_t vpi2creg = reg % SCMD_REG_SIZE;
312 	uint8_t vpi2caddr = (SCMD_REMOTE_ADDR_LOW + loc) - 1;
313 
314 	DPRINTF(sc, 2, ("%s: View port addr: %02x ; View port register: %02x ; Orig register: %04x\n",
315 	    device_xname(sc->sc_dev), vpi2caddr, vpi2creg, reg));
316 
317 	err = (*(sc->sc_func_write_register))(sc, SCMD_REG_REM_ADDR, vpi2caddr);
318 	if (! err)
319 		err = (*(sc->sc_func_write_register))(sc, SCMD_REG_REM_OFFSET, vpi2creg);
320 
321 	return err;
322 }
323 
324 /* It is not defined what happens if the Not Defined in the datasheet
325  * registers are accessed, so block them.
326  */
327 static int
scmd_local_read(struct scmd_sc * sc,uint8_t reg,uint8_t * buf)328 scmd_local_read(struct scmd_sc *sc, uint8_t reg, uint8_t *buf)
329 {
330 	if (SCMD_IS_HOLE(reg)) {
331 		*buf = SCMD_HOLE_VALUE;
332 		return 0;
333 	}
334 
335 	return (*(sc->sc_func_read_register))(sc, reg, buf);
336 }
337 
338 static int
scmd_remote_read(struct scmd_sc * sc,int reg,uint8_t * buf)339 scmd_remote_read(struct scmd_sc *sc, int reg, uint8_t *buf)
340 {
341 	int err;
342 	int c;
343 	uint8_t b;
344 
345 	if (SCMD_IS_HOLE(reg % SCMD_REG_SIZE)) {
346 		*buf = SCMD_HOLE_VALUE;
347 		return 0;
348 	}
349 
350 	err = scmd_set_view_port(sc, reg);
351 	if (! err) {
352 		b = 0xff; /* you can write anything here.. it doesn't matter */
353 		err = (*(sc->sc_func_write_register))(sc, SCMD_REG_REM_READ, b);
354 		if (! err) {
355 			/* So ...  there is no way to really know that the data is ready and
356 			 * there is no way to know if there was an error in the master module reading
357 			 * the data from the slave module.  The data sheet says wait 5ms.. so do that
358 			 * and see if the register cleared, but don't wait forever...  I can't see how
359 			 * it would not be possible to read junk at times.
360 			 */
361 			c = 0;
362 			do {
363 				delay(5000);
364 				err = (*(sc->sc_func_read_register))(sc, SCMD_REG_REM_READ, &b);
365 				c++;
366 			} while ((c < 10) && (b != 0x00) && (!err));
367 			/* We can only hope that whatever was read from the slave module is there */
368 			if (! err)
369 				err = (*(sc->sc_func_read_register))(sc, SCMD_REG_REM_DATA_RD, buf);
370 		}
371 	}
372 
373 	return err;
374 }
375 
376 static int
scmd_read(dev_t dev,struct uio * uio,int flags)377 scmd_read(dev_t dev, struct uio *uio, int flags)
378 {
379 	struct scmd_sc *sc;
380 	int error;
381 
382 	if ((sc = device_lookup_private(&scmd_cd, minor(dev))) == NULL)
383 		return ENXIO;
384 
385 	/* We do not make this an error.  There is nothing wrong with running
386 	 * off the end here, just return EOF.
387 	 */
388 	if (uio->uio_offset > scmd_maxregister(sc->sc_topaddr))
389 		return 0;
390 
391 	if ((error = (*(sc->sc_func_acquire_bus))(sc)) != 0)
392 		return error;
393 
394 	while (uio->uio_resid &&
395 	    uio->uio_offset <= scmd_maxregister(sc->sc_topaddr) &&
396 	    !sc->sc_dying) {
397 		uint8_t buf;
398 		int reg_addr = uio->uio_offset;
399 
400 		if (reg_addr <= SCMD_LAST_REG) {
401 			if ((error = scmd_local_read(sc, (uint8_t)reg_addr, &buf)) != 0) {
402 				(*(sc->sc_func_release_bus))(sc);
403 				aprint_error_dev(sc->sc_dev,
404 				    "%s: local read failed at 0x%02x: %d\n",
405 				    __func__, reg_addr, error);
406 				return error;
407 			}
408 		} else {
409 			if ((error = scmd_remote_read(sc, reg_addr, &buf)) != 0) {
410 				(*(sc->sc_func_release_bus))(sc);
411 				aprint_error_dev(sc->sc_dev,
412 				    "%s: remote read failed at 0x%02x: %d\n",
413 				    __func__, reg_addr, error);
414 				return error;
415 			}
416 		}
417 
418 		if (sc->sc_dying)
419 			break;
420 
421 		if ((error = uiomove(&buf, 1, uio)) != 0) {
422 			(*(sc->sc_func_release_bus))(sc);
423 			return error;
424 		}
425 	}
426 
427 	(*(sc->sc_func_release_bus))(sc);
428 
429 	if (sc->sc_dying) {
430 		return EIO;
431 	}
432 
433 	return 0;
434 }
435 
436 /* Same thing about the undefined registers.  Don't actually allow
437  * writes as it is not clear what happens when you do that.
438  */
439 static int
scmd_local_write(struct scmd_sc * sc,uint8_t reg,uint8_t buf)440 scmd_local_write(struct scmd_sc *sc, uint8_t reg, uint8_t buf)
441 {
442 	if (SCMD_IS_HOLE(reg))
443 		return 0;
444 
445 	return (*(sc->sc_func_write_register))(sc, reg, buf);
446 }
447 
448 static int
scmd_remote_write(struct scmd_sc * sc,int reg,uint8_t buf)449 scmd_remote_write(struct scmd_sc *sc, int reg, uint8_t buf)
450 {
451 	int err;
452 	int c;
453 	uint8_t b;
454 
455 	if (SCMD_IS_HOLE(reg % SCMD_REG_SIZE)) {
456 		return 0;
457 	}
458 
459 	err = scmd_set_view_port(sc, reg);
460 	if (! err) {
461 		/* We just sort of send this write off and wait to see if the register
462 		 * clears.  There really isn't any indication that the data made it to the
463 		 * slave modules and there really are not any errors reported.
464 		 */
465 		err = (*(sc->sc_func_write_register))(sc, SCMD_REG_REM_DATA_WR, buf);
466 		if (! err) {
467 			b = 0xff; /* you can write anything here.. it doesn't matter */
468 			err = (*(sc->sc_func_write_register))(sc, SCMD_REG_REM_WRITE, b);
469 			if (! err) {
470 				c = 0;
471 				do {
472 					delay(5000);
473 					err = (*(sc->sc_func_read_register))(sc, SCMD_REG_REM_WRITE, &b);
474 					c++;
475 				} while ((c < 10) && (b != 0x00) && (!err));
476 			}
477 		}
478 	}
479 
480 	return err;
481 }
482 
483 static int
scmd_write(dev_t dev,struct uio * uio,int flags)484 scmd_write(dev_t dev, struct uio *uio, int flags)
485 {
486 	struct scmd_sc *sc;
487 	int error;
488 
489 	if ((sc = device_lookup_private(&scmd_cd, minor(dev))) == NULL)
490 		return ENXIO;
491 
492 	/* Same thing as read, this is not considered an error */
493 	if (uio->uio_offset > scmd_maxregister(sc->sc_topaddr))
494 		return 0;
495 
496 	if ((error = (*(sc->sc_func_acquire_bus))(sc)) != 0)
497 		return error;
498 
499 	while (uio->uio_resid &&
500 	    uio->uio_offset <= scmd_maxregister(sc->sc_topaddr) &&
501 	    !sc->sc_dying) {
502 		uint8_t buf;
503 		int reg_addr = uio->uio_offset;
504 
505 		if ((error = uiomove(&buf, 1, uio)) != 0)
506 			break;
507 
508 		if (sc->sc_dying)
509 			break;
510 
511 		if (reg_addr <= SCMD_LAST_REG) {
512 			if ((error = scmd_local_write(sc, (uint8_t)reg_addr, buf)) != 0) {
513 				(*(sc->sc_func_release_bus))(sc);
514 				aprint_error_dev(sc->sc_dev,
515 				    "%s: local write failed at 0x%02x: %d\n",
516 				    __func__, reg_addr, error);
517 				return error;
518 			}
519 
520 			/* If this was a local command to the control register that
521 			 * can perform re-enumeration, then do the wait thing.
522 			 * It is not as important that this be done for remote module
523 			 * access as the only thing that you could really do there is
524 			 * a restart and not re-enumeration, which is really what the wait
525 			 * is all about.
526 			 */
527 			if (reg_addr == SCMD_REG_CONTROL_1) {
528 				scmd_wait_restart(sc, false);
529 
530 				sc->sc_topaddr = scmd_get_topaddr(sc);
531 				aprint_normal_dev(sc->sc_dev, "Highest I2C address on expansion bus is: %02x\n",
532 				    sc->sc_topaddr);
533 			}
534 		} else {
535 			if ((error = scmd_remote_write(sc, reg_addr, buf)) != 0) {
536 				(*(sc->sc_func_release_bus))(sc);
537 				aprint_error_dev(sc->sc_dev,
538 				    "%s: remote write failed at 0x%02x: %d\n",
539 				    __func__, reg_addr, error);
540 				return error;
541 			}
542 		}
543 	}
544 
545 	(*(sc->sc_func_release_bus))(sc);
546 
547 	if (sc->sc_dying) {
548 		return EIO;
549 	}
550 
551 	return error;
552 }
553 
554 static int
scmd_close(dev_t dev,int flags,int fmt,struct lwp * l)555 scmd_close(dev_t dev, int flags, int fmt, struct lwp *l)
556 {
557 	struct scmd_sc *sc;
558 
559 	sc = device_lookup_private(&scmd_cd, minor(dev));
560 
561 	if (sc->sc_dying) {
562 		DPRINTF(sc, 2, ("%s: Telling all we are almost dead\n",
563 		    device_xname(sc->sc_dev)));
564 		mutex_enter(&sc->sc_dying_mutex);
565 		cv_signal(&sc->sc_cond_dying);
566 		mutex_exit(&sc->sc_dying_mutex);
567 		return EIO;
568 	}
569 
570 	mutex_enter(&sc->sc_mutex);
571 	sc->sc_opened = false;
572 	mutex_exit(&sc->sc_mutex);
573 
574 	return(0);
575 }
576 
577 MODULE(MODULE_CLASS_DRIVER, scmd, NULL);
578 
579 #ifdef _MODULE
580 CFDRIVER_DECL(scmd, DV_DULL, NULL);
581 #include "ioconf.c"
582 #endif
583 
584 static int
scmd_modcmd(modcmd_t cmd,void * opaque)585 scmd_modcmd(modcmd_t cmd, void *opaque)
586 {
587 #ifdef _MODULE
588 	int error = 0;
589 	int bmaj = -1, cmaj = -1;
590 #endif
591 
592 	switch (cmd) {
593 	case MODULE_CMD_INIT:
594 #ifdef _MODULE
595 		error = devsw_attach("scmd", NULL, &bmaj,
596 		    &scmd_cdevsw, &cmaj);
597 		if (error) {
598 			aprint_error("%s: unable to attach devsw: %d\n",
599 			    scmd_cd.cd_name, error);
600 			return error;
601 		}
602 
603 		error = config_init_component(cfdriver_ioconf_scmd,
604 		    cfattach_ioconf_scmd, cfdata_ioconf_scmd);
605 		if (error) {
606 			aprint_error("%s: unable to init component: %d\n",
607 			    scmd_cd.cd_name, error);
608 			devsw_detach(NULL, &scmd_cdevsw);
609 		}
610 		return error;
611 #else
612 		return 0;
613 #endif
614 	case MODULE_CMD_FINI:
615 #ifdef _MODULE
616 		error = config_fini_component(cfdriver_ioconf_scmd,
617 		    cfattach_ioconf_scmd, cfdata_ioconf_scmd);
618 		devsw_detach(NULL, &scmd_cdevsw);
619 
620 		return error;
621 #else
622 		return 0;
623 #endif
624 	default:
625 		return ENOTTY;
626 	}
627 }
628