1 /* $NetBSD: j720tp.c,v 1.8 2007/10/26 10:39:40 peter Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by IWAMOTO Toshihiro and Peter Postma. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* Jornada 720 touch-panel driver. */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: j720tp.c,v 1.8 2007/10/26 10:39:40 peter Exp $"); 43 44 #ifdef _KERNEL_OPT 45 #include "opt_j720tp.h" 46 #include "opt_wsdisplay_compat.h" 47 #endif 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/device.h> 52 #include <sys/kernel.h> 53 #include <sys/malloc.h> 54 #include <sys/ioctl.h> 55 #include <sys/callout.h> 56 #include <sys/sysctl.h> 57 58 #include <machine/platid.h> 59 #include <machine/platid_mask.h> 60 61 #include <arm/sa11x0/sa11x0_var.h> 62 #include <arm/sa11x0/sa11x0_gpioreg.h> 63 #include <arm/sa11x0/sa11x0_ppcreg.h> 64 #include <arm/sa11x0/sa11x0_sspreg.h> 65 66 #include <dev/wscons/wsconsio.h> 67 #include <dev/wscons/wsmousevar.h> 68 #include <dev/wscons/wskbdvar.h> 69 #include <dev/wscons/wsksymvar.h> 70 #include <dev/wscons/wsksymdef.h> 71 #include <dev/hpc/hpctpanelvar.h> 72 73 #include <hpcarm/dev/j720sspvar.h> 74 75 #ifdef WSDISPLAY_COMPAT_RAWKBD 76 #include <dev/hpc/pckbd_encode.h> 77 #endif 78 79 #define arraysize(ary) (sizeof(ary) / sizeof(ary[0])) 80 81 #ifdef J720TP_DEBUG 82 int j720tp_debug = 0; 83 #define DPRINTF(arg) if (j720tp_debug) printf arg 84 #define DPRINTFN(n, arg) if (j720tp_debug >= (n)) printf arg 85 #else 86 #define DPRINTF(arg) /* nothing */ 87 #define DPRINTFN(n, arg) /* nothing */ 88 #endif 89 90 struct j720tp_softc { 91 struct device sc_dev; 92 93 #define J720TP_WSMOUSE_ENABLED 0x01 94 #define J720TP_WSKBD_ENABLED 0x02 95 int sc_enabled; 96 int sc_hard_icon; 97 #ifdef WSDISPLAY_COMPAT_RAWKBD 98 int sc_rawkbd; 99 #endif 100 101 struct callout sc_tpcallout; 102 struct j720ssp_softc *sc_ssp; 103 104 struct device *sc_wsmousedev; 105 struct device *sc_wskbddev; 106 107 struct tpcalib_softc sc_tpcalib; 108 }; 109 110 static int j720tp_match(struct device *, struct cfdata *, void *); 111 static void j720tp_attach(struct device *, struct device *, void *); 112 113 static int j720tp_wsmouse_enable(void *); 114 static int j720tp_wsmouse_ioctl(void *, u_long, void *, int, 115 struct lwp *); 116 static void j720tp_wsmouse_disable(void *); 117 118 static int j720tp_wskbd_enable(void *, int); 119 static void j720tp_wskbd_set_leds(void *, int); 120 static int j720tp_wskbd_ioctl(void *, u_long, void *, int, struct lwp *); 121 122 static void j720tp_enable_intr(struct j720tp_softc *); 123 static void j720tp_disable_intr(struct j720tp_softc *); 124 static int j720tp_intr(void *); 125 static int j720tp_get_rawxy(struct j720tp_softc *, int *, int *); 126 static int j720tp_get_hard_icon(struct j720tp_softc *, int, int); 127 static void j720tp_wsmouse_input(struct j720tp_softc *, int, int); 128 static void j720tp_wsmouse_callout(void *); 129 static void j720tp_wskbd_input(struct j720tp_softc *, u_int); 130 static void j720tp_wskbd_callout(void *); 131 132 const struct wsmouse_accessops j720tp_wsmouse_accessops = { 133 j720tp_wsmouse_enable, 134 j720tp_wsmouse_ioctl, 135 j720tp_wsmouse_disable 136 }; 137 138 static const struct wsmouse_calibcoords j720tp_default_calib = { 139 0, 0, 639, 239, 140 4, 141 {{ 988, 80, 0, 0 }, 142 { 88, 84, 639, 0 }, 143 { 988, 927, 0, 239 }, 144 { 88, 940, 639, 239 }} 145 }; 146 147 const struct wskbd_accessops j720tp_wskbd_accessops = { 148 j720tp_wskbd_enable, 149 j720tp_wskbd_set_leds, 150 j720tp_wskbd_ioctl 151 }; 152 153 #ifndef J720TP_SETTINGS_ICON_KEYSYM 154 #define J720TP_SETTINGS_ICON_KEYSYM KS_Home 155 #endif 156 #ifndef J720TP_BACKUP_ICON_KEYSYM 157 #define J720TP_BACKUP_ICON_KEYSYM KS_Prior 158 #endif 159 #ifndef J720TP_DIALUP_ICON_KEYSYM 160 #define J720TP_DIALUP_ICON_KEYSYM KS_Next 161 #endif 162 #ifndef J720TP_MEDIA_ICON_KEYSYM 163 #define J720TP_MEDIA_ICON_KEYSYM KS_End 164 #endif 165 166 /* Max Y value of the n'th hard icon. */ 167 #define J720TP_HARD_ICON_MAX_Y(n) \ 168 (((j720tp_hard_icon_bottom - j720tp_hard_icon_top) / 4) * (n)) + \ 169 j720tp_hard_icon_top 170 171 /* Default raw X/Y values of the hard icon area. */ 172 static int j720tp_hard_icon_left = 70; 173 static int j720tp_hard_icon_right = 20; 174 static int j720tp_hard_icon_top = 70; 175 static int j720tp_hard_icon_bottom = 940; 176 177 /* Maps the icon number to a raw keycode. */ 178 static const int j720tp_wskbd_keys[] = { 179 /* Icon 1 */ 199, 180 /* Icon 2 */ 201, 181 /* Icon 3 */ 209, 182 /* Icon 4 */ 207 183 }; 184 185 static const keysym_t j720tp_wskbd_keydesc[] = { 186 KS_KEYCODE(199), J720TP_SETTINGS_ICON_KEYSYM, 187 KS_KEYCODE(201), J720TP_BACKUP_ICON_KEYSYM, 188 KS_KEYCODE(209), J720TP_DIALUP_ICON_KEYSYM, 189 KS_KEYCODE(207), J720TP_MEDIA_ICON_KEYSYM 190 }; 191 192 const struct wscons_keydesc j720tp_wskbd_keydesctab[] = { 193 { KB_US, 0, 194 sizeof(j720tp_wskbd_keydesc) / sizeof(keysym_t), 195 j720tp_wskbd_keydesc 196 }, 197 { 0, 0, 0, 0 } 198 }; 199 200 const struct wskbd_mapdata j720tp_wskbd_keymapdata = { 201 j720tp_wskbd_keydesctab, KB_US 202 }; 203 204 CFATTACH_DECL(j720tp, sizeof(struct j720tp_softc), 205 j720tp_match, j720tp_attach, NULL, NULL); 206 207 208 static int 209 j720tp_match(struct device *parent, struct cfdata *cf, void *aux) 210 { 211 212 if (!platid_match(&platid, &platid_mask_MACH_HP_JORNADA_7XX)) 213 return 0; 214 if (strcmp(cf->cf_name, "j720tp") != 0) 215 return 0; 216 217 return 1; 218 } 219 220 static void 221 j720tp_attach(struct device *parent, struct device *self, void *aux) 222 { 223 struct j720tp_softc *sc = (struct j720tp_softc *)self; 224 struct wsmousedev_attach_args wsma; 225 struct wskbddev_attach_args wska; 226 227 printf("\n"); 228 229 sc->sc_ssp = (struct j720ssp_softc *)parent; 230 sc->sc_enabled = 0; 231 sc->sc_hard_icon = 0; 232 sc->sc_rawkbd = 0; 233 234 /* Touch-panel as a pointing device. */ 235 wsma.accessops = &j720tp_wsmouse_accessops; 236 wsma.accesscookie = sc; 237 238 sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &wsma, 239 wsmousedevprint); 240 if (sc->sc_wsmousedev == NULL) 241 return; 242 243 /* Initialize calibration, set default parameters. */ 244 tpcalib_init(&sc->sc_tpcalib); 245 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 246 __UNCONST(&j720tp_default_calib), 0, 0); 247 248 callout_init(&sc->sc_tpcallout, 0); 249 250 j720tp_wsmouse_disable(sc); 251 252 /* On-screen "hard icons" as a keyboard device. */ 253 wska.console = 0; 254 wska.keymap = &j720tp_wskbd_keymapdata; 255 wska.accessops = &j720tp_wskbd_accessops; 256 wska.accesscookie = sc; 257 258 sc->sc_wskbddev = config_found_ia(self, "wskbddev", &wska, 259 wskbddevprint); 260 261 /* Setup touch-panel interrupt. */ 262 sa11x0_intr_establish(0, 9, 1, IPL_TTY, j720tp_intr, sc); 263 } 264 265 static int 266 j720tp_wsmouse_enable(void *self) 267 { 268 struct j720tp_softc *sc = self; 269 int s; 270 271 s = spltty(); 272 273 j720tp_enable_intr(sc); 274 275 sc->sc_enabled |= J720TP_WSMOUSE_ENABLED; 276 277 splx(s); 278 return 0; 279 } 280 281 static int 282 j720tp_wsmouse_ioctl(void *self, u_long cmd, void *data, int flag, 283 struct lwp *l) 284 { 285 struct j720tp_softc *sc = self; 286 287 return hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 288 } 289 290 static void 291 j720tp_wsmouse_disable(void *self) 292 { 293 struct j720tp_softc *sc = self; 294 int s; 295 296 s = spltty(); 297 298 j720tp_disable_intr(sc); 299 callout_stop(&sc->sc_tpcallout); 300 301 sc->sc_enabled &= ~J720TP_WSMOUSE_ENABLED; 302 303 splx(s); 304 } 305 306 static int 307 j720tp_wskbd_enable(void *self, int on) 308 { 309 struct j720tp_softc *sc = self; 310 int s; 311 312 s = spltty(); 313 sc->sc_enabled |= J720TP_WSKBD_ENABLED; 314 splx(s); 315 316 return 0; 317 } 318 319 static void 320 j720tp_wskbd_set_leds(void *self, int leds) 321 { 322 /* nothing to do */ 323 } 324 325 static int 326 j720tp_wskbd_ioctl(void *self, u_long cmd, void *data, int flag, 327 struct lwp *l) 328 { 329 #ifdef WSDISPLAY_COMPAT_RAWKBD 330 struct j720tp_softc *sc = self; 331 #endif 332 333 switch (cmd) { 334 case WSKBDIO_GTYPE: 335 *(int *)data = WSKBD_TYPE_HPC_BTN; 336 return 0; 337 case WSKBDIO_GETLEDS: 338 *(int *)data = 0; 339 return 0; 340 #ifdef WSDISPLAY_COMPAT_RAWKBD 341 case WSKBDIO_SETMODE: 342 sc->sc_rawkbd = (*(int *)data == WSKBD_RAW); 343 return 0; 344 #endif 345 } 346 347 return EPASSTHROUGH; 348 } 349 350 /* 351 * Enable touch-panel interrupt. Must be called at spltty(). 352 */ 353 static void 354 j720tp_enable_intr(struct j720tp_softc *sc) 355 { 356 struct j720ssp_softc *ssp = sc->sc_ssp; 357 uint32_t er; 358 359 er = bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER); 360 er |= 1 << 9; 361 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER, er); 362 } 363 364 /* 365 * Disable touch-panel interrupt. Must be called at spltty(). 366 */ 367 static void 368 j720tp_disable_intr(struct j720tp_softc *sc) 369 { 370 struct j720ssp_softc *ssp = sc->sc_ssp; 371 uint32_t er; 372 373 er = bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER); 374 er &= ~(1 << 9); 375 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER, er); 376 } 377 378 static int 379 j720tp_intr(void *arg) 380 { 381 struct j720tp_softc *sc = arg; 382 struct j720ssp_softc *ssp = sc->sc_ssp; 383 int rawx, rawy; 384 385 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_EDR, 1 << 9); 386 387 if (!(sc->sc_enabled & J720TP_WSMOUSE_ENABLED)) { 388 DPRINTF(("j720tp_intr: !sc_enabled\n")); 389 return 0; 390 } 391 392 j720tp_disable_intr(sc); 393 394 if (j720tp_get_rawxy(sc, &rawx, &rawy)) { 395 sc->sc_hard_icon = j720tp_get_hard_icon(sc, rawx, rawy); 396 397 if (sc->sc_hard_icon > 0) { 398 j720tp_wskbd_input(sc, WSCONS_EVENT_KEY_DOWN); 399 callout_reset(&sc->sc_tpcallout, hz / 32, 400 j720tp_wskbd_callout, sc); 401 } else { 402 j720tp_wsmouse_input(sc, rawx, rawy); 403 callout_reset(&sc->sc_tpcallout, hz / 32, 404 j720tp_wsmouse_callout, sc); 405 } 406 } 407 408 return 1; 409 } 410 411 static int 412 j720tp_get_rawxy(struct j720tp_softc *sc, int *rawx, int *rawy) 413 { 414 struct j720ssp_softc *ssp = sc->sc_ssp; 415 int buf[8], data, i; 416 417 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PCR, 0x2000000); 418 419 /* Send read touch-panel command. */ 420 if (j720ssp_readwrite(ssp, 1, 0xa0, &data, 100) < 0 || data != 0x11) { 421 DPRINTF(("j720tp_get_rawxy: no dummy received\n")); 422 goto out; 423 } 424 425 for (i = 0; i < 8; i++) { 426 if (j720ssp_readwrite(ssp, 0, 0x11, &data, 100) < 0) 427 goto out; 428 buf[i] = data; 429 } 430 431 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 432 433 buf[6] <<= 8; 434 buf[7] <<= 8; 435 for (i = 0; i < 3; i++) { 436 buf[i] |= buf[6] & 0x300; 437 buf[6] >>= 2; 438 buf[i + 3] |= buf[7] & 0x300; 439 buf[7] >>= 2; 440 } 441 442 DPRINTFN(2, ("j720tp_get_rawxy: %d:%d:%d:%d:%d:%d:%d:%d\n", 443 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])); 444 445 *rawx = buf[1]; 446 *rawy = buf[4]; 447 448 return 1; 449 out: 450 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 451 452 /* reset SSP */ 453 bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x307); 454 delay(100); 455 bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x387); 456 457 DPRINTF(("j720tp_get_rawxy: error %x\n", data)); 458 return 0; 459 } 460 461 static int 462 j720tp_get_hard_icon(struct j720tp_softc *sc, int rawx, int rawy) 463 { 464 int icon = 0; 465 466 if (!(sc->sc_enabled & J720TP_WSKBD_ENABLED)) 467 return 0; 468 /* Check if the touch was in the hard icons area. */ 469 if (rawx > j720tp_hard_icon_left) 470 return 0; 471 472 if (rawy < J720TP_HARD_ICON_MAX_Y(1)) 473 icon = 1; 474 else if (rawy < J720TP_HARD_ICON_MAX_Y(2)) 475 icon = 2; 476 else if (rawy < J720TP_HARD_ICON_MAX_Y(3)) 477 icon = 3; 478 else if (rawy < J720TP_HARD_ICON_MAX_Y(4)) 479 icon = 4; 480 481 return icon; 482 } 483 484 static void 485 j720tp_wsmouse_input(struct j720tp_softc *sc, int rawx, int rawy) 486 { 487 int x, y; 488 489 tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); 490 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, 0, 491 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 492 } 493 494 static void 495 j720tp_wsmouse_callout(void *arg) 496 { 497 struct j720tp_softc *sc = arg; 498 struct j720ssp_softc *ssp = sc->sc_ssp; 499 int rawx, rawy, s; 500 501 s = spltty(); 502 503 if (!(sc->sc_enabled & J720TP_WSMOUSE_ENABLED)) { 504 DPRINTF(("j720tp_wsmouse_callout: !sc_enabled\n")); 505 splx(s); 506 return; 507 } 508 509 if (bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PLR) & (1<<9)) { 510 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0, 0); 511 j720tp_enable_intr(sc); 512 } else { 513 if (j720tp_get_rawxy(sc, &rawx, &rawy)) 514 j720tp_wsmouse_input(sc, rawx, rawy); 515 callout_schedule(&sc->sc_tpcallout, hz / 32); 516 } 517 518 splx(s); 519 } 520 521 static void 522 j720tp_wskbd_input(struct j720tp_softc *sc, u_int evtype) 523 { 524 int key = j720tp_wskbd_keys[sc->sc_hard_icon - 1]; 525 526 #ifdef WSDISPLAY_COMPAT_RAWKBD 527 if (sc->sc_rawkbd) { 528 int n; 529 u_char data[16]; 530 531 n = pckbd_encode(evtype, key, data); 532 wskbd_rawinput(sc->sc_wskbddev, data, n); 533 } else 534 #endif 535 wskbd_input(sc->sc_wskbddev, evtype, key); 536 } 537 538 static void 539 j720tp_wskbd_callout(void *arg) 540 { 541 struct j720tp_softc *sc = arg; 542 struct j720ssp_softc *ssp = sc->sc_ssp; 543 int s; 544 545 s = spltty(); 546 547 if (!sc->sc_enabled) { 548 DPRINTF(("j720tp_wskbd_callout: !sc_enabled\n")); 549 splx(s); 550 return; 551 } 552 553 if (bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PLR) & (1<<9)) { 554 j720tp_wskbd_input(sc, WSCONS_EVENT_KEY_UP); 555 j720tp_enable_intr(sc); 556 } else { 557 callout_schedule(&sc->sc_tpcallout, hz / 32); 558 } 559 560 splx(s); 561 } 562 563 SYSCTL_SETUP(sysctl_j720tp, "sysctl j720tp subtree setup") 564 { 565 const struct sysctlnode *rnode; 566 int rc; 567 568 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 569 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 570 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 571 goto err; 572 573 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 574 CTLFLAG_PERMANENT, CTLTYPE_NODE, "j720tp", 575 SYSCTL_DESCR("Jornada 720 touch panel controls"), 576 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 577 goto err; 578 579 #ifdef J720TP_DEBUG 580 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 581 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 582 SYSCTL_DESCR("Verbosity of debugging messages"), 583 NULL, 0, &j720tp_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 584 goto err; 585 #endif /* J720TP_DEBUG */ 586 587 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 588 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hard_icons", 589 SYSCTL_DESCR("Touch panel hard icons controls"), 590 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 591 goto err; 592 593 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 594 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "left", 595 SYSCTL_DESCR("Raw left X value of the hard icon area"), 596 NULL, 0, &j720tp_hard_icon_left, 0, CTL_CREATE, CTL_EOL)) != 0) 597 goto err; 598 599 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 600 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "right", 601 SYSCTL_DESCR("Raw right X value of the hard icon area"), 602 NULL, 0, &j720tp_hard_icon_right, 0, CTL_CREATE, CTL_EOL)) != 0) 603 goto err; 604 605 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 606 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "top", 607 SYSCTL_DESCR("Raw top Y value of the hard icon area"), 608 NULL, 0, &j720tp_hard_icon_top, 0, CTL_CREATE, CTL_EOL)) != 0) 609 goto err; 610 611 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 612 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "bottom", 613 SYSCTL_DESCR("Raw bottom Y value of the hard icon area"), 614 NULL, 0, &j720tp_hard_icon_bottom, 0, CTL_CREATE, CTL_EOL)) != 0) 615 goto err; 616 617 return; 618 err: 619 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 620 } 621