1 /* $NetBSD: j720tp.c,v 1.6 2007/07/12 22:02:39 he 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.6 2007/07/12 22:02:39 he 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 j720tp_wsmouse_disable(sc); 249 callout_init(&sc->sc_tpcallout, 0); 250 251 /* On-screen "hard icons" as a keyboard device. */ 252 wska.console = 0; 253 wska.keymap = &j720tp_wskbd_keymapdata; 254 wska.accessops = &j720tp_wskbd_accessops; 255 wska.accesscookie = sc; 256 257 sc->sc_wskbddev = config_found_ia(self, "wskbddev", &wska, 258 wskbddevprint); 259 260 /* Setup touch-panel interrupt. */ 261 sa11x0_intr_establish(0, 9, 1, IPL_TTY, j720tp_intr, sc); 262 } 263 264 static int 265 j720tp_wsmouse_enable(void *self) 266 { 267 struct j720tp_softc *sc = self; 268 int s; 269 270 s = spltty(); 271 272 j720tp_enable_intr(sc); 273 274 sc->sc_enabled |= J720TP_WSMOUSE_ENABLED; 275 276 splx(s); 277 return 0; 278 } 279 280 static int 281 j720tp_wsmouse_ioctl(void *self, u_long cmd, void *data, int flag, 282 struct lwp *l) 283 { 284 struct j720tp_softc *sc = self; 285 286 return hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 287 } 288 289 static void 290 j720tp_wsmouse_disable(void *self) 291 { 292 struct j720tp_softc *sc = self; 293 int s; 294 295 s = spltty(); 296 297 j720tp_disable_intr(sc); 298 callout_stop(&sc->sc_tpcallout); 299 300 sc->sc_enabled &= ~J720TP_WSMOUSE_ENABLED; 301 302 splx(s); 303 } 304 305 static int 306 j720tp_wskbd_enable(void *self, int on) 307 { 308 struct j720tp_softc *sc = self; 309 int s; 310 311 s = spltty(); 312 sc->sc_enabled |= J720TP_WSKBD_ENABLED; 313 splx(s); 314 315 return 0; 316 } 317 318 static void 319 j720tp_wskbd_set_leds(void *self, int leds) 320 { 321 /* nothing to do */ 322 } 323 324 static int 325 j720tp_wskbd_ioctl(void *self, u_long cmd, void *data, int flag, 326 struct lwp *l) 327 { 328 #ifdef WSDISPLAY_COMPAT_RAWKBD 329 struct j720tp_softc *sc = self; 330 #endif 331 332 switch (cmd) { 333 case WSKBDIO_GTYPE: 334 *(int *)data = WSKBD_TYPE_HPC_BTN; 335 return 0; 336 case WSKBDIO_GETLEDS: 337 *(int *)data = 0; 338 return 0; 339 #ifdef WSDISPLAY_COMPAT_RAWKBD 340 case WSKBDIO_SETMODE: 341 sc->sc_rawkbd = (*(int *)data == WSKBD_RAW); 342 return 0; 343 #endif 344 } 345 346 return EPASSTHROUGH; 347 } 348 349 /* 350 * Enable touch-panel interrupt. Must be called at spltty(). 351 */ 352 static void 353 j720tp_enable_intr(struct j720tp_softc *sc) 354 { 355 struct j720ssp_softc *ssp = sc->sc_ssp; 356 uint32_t er; 357 358 er = bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER); 359 er |= 1 << 9; 360 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER, er); 361 } 362 363 /* 364 * Disable touch-panel interrupt. Must be called at spltty(). 365 */ 366 static void 367 j720tp_disable_intr(struct j720tp_softc *sc) 368 { 369 struct j720ssp_softc *ssp = sc->sc_ssp; 370 uint32_t er; 371 372 er = bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER); 373 er &= ~(1 << 9); 374 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_FER, er); 375 } 376 377 static int 378 j720tp_intr(void *arg) 379 { 380 struct j720tp_softc *sc = arg; 381 struct j720ssp_softc *ssp = sc->sc_ssp; 382 int rawx, rawy; 383 384 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_EDR, 1 << 9); 385 386 if (!(sc->sc_enabled & J720TP_WSMOUSE_ENABLED)) { 387 DPRINTF(("j720tp_intr: !sc_enabled\n")); 388 return 0; 389 } 390 391 j720tp_disable_intr(sc); 392 393 if (j720tp_get_rawxy(sc, &rawx, &rawy)) { 394 sc->sc_hard_icon = j720tp_get_hard_icon(sc, rawx, rawy); 395 396 if (sc->sc_hard_icon > 0) { 397 j720tp_wskbd_input(sc, WSCONS_EVENT_KEY_DOWN); 398 callout_reset(&sc->sc_tpcallout, hz / 32, 399 j720tp_wskbd_callout, sc); 400 } else { 401 j720tp_wsmouse_input(sc, rawx, rawy); 402 callout_reset(&sc->sc_tpcallout, hz / 32, 403 j720tp_wsmouse_callout, sc); 404 } 405 } 406 407 return 1; 408 } 409 410 static int 411 j720tp_get_rawxy(struct j720tp_softc *sc, int *rawx, int *rawy) 412 { 413 struct j720ssp_softc *ssp = sc->sc_ssp; 414 int buf[8], data, i; 415 416 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PCR, 0x2000000); 417 418 /* Send read touch-panel command. */ 419 if (j720ssp_readwrite(ssp, 1, 0xa0, &data, 100) < 0 || data != 0x11) { 420 DPRINTF(("j720tp_get_rawxy: no dummy received\n")); 421 goto out; 422 } 423 424 for (i = 0; i < 8; i++) { 425 if (j720ssp_readwrite(ssp, 0, 0x11, &data, 100) < 0) 426 goto out; 427 buf[i] = data; 428 } 429 430 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 431 432 buf[6] <<= 8; 433 buf[7] <<= 8; 434 for (i = 0; i < 3; i++) { 435 buf[i] |= buf[6] & 0x300; 436 buf[6] >>= 2; 437 buf[i + 3] |= buf[7] & 0x300; 438 buf[7] >>= 2; 439 } 440 441 DPRINTFN(2, ("j720tp_get_rawxy: %d:%d:%d:%d:%d:%d:%d:%d\n", 442 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7])); 443 444 *rawx = buf[1]; 445 *rawy = buf[4]; 446 447 return 1; 448 out: 449 bus_space_write_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PSR, 0x2000000); 450 451 /* reset SSP */ 452 bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x307); 453 delay(100); 454 bus_space_write_4(ssp->sc_iot, ssp->sc_ssph, SASSP_CR0, 0x387); 455 456 DPRINTF(("j720tp_get_rawxy: error %x\n", data)); 457 return 0; 458 } 459 460 static int 461 j720tp_get_hard_icon(struct j720tp_softc *sc, int rawx, int rawy) 462 { 463 int icon = 0; 464 465 if (!(sc->sc_enabled & J720TP_WSKBD_ENABLED)) 466 return 0; 467 /* Check if the touch was in the hard icons area. */ 468 if (rawx > j720tp_hard_icon_left) 469 return 0; 470 471 if (rawy < J720TP_HARD_ICON_MAX_Y(1)) 472 icon = 1; 473 else if (rawy < J720TP_HARD_ICON_MAX_Y(2)) 474 icon = 2; 475 else if (rawy < J720TP_HARD_ICON_MAX_Y(3)) 476 icon = 3; 477 else if (rawy < J720TP_HARD_ICON_MAX_Y(4)) 478 icon = 4; 479 480 return icon; 481 } 482 483 static void 484 j720tp_wsmouse_input(struct j720tp_softc *sc, int rawx, int rawy) 485 { 486 int x, y; 487 488 tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); 489 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, 0, 490 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 491 } 492 493 static void 494 j720tp_wsmouse_callout(void *arg) 495 { 496 struct j720tp_softc *sc = arg; 497 struct j720ssp_softc *ssp = sc->sc_ssp; 498 int rawx, rawy, s; 499 500 s = spltty(); 501 502 if (!(sc->sc_enabled & J720TP_WSMOUSE_ENABLED)) { 503 DPRINTF(("j720tp_wsmouse_callout: !sc_enabled\n")); 504 splx(s); 505 return; 506 } 507 508 if (bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PLR) & (1<<9)) { 509 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0, 0); 510 j720tp_enable_intr(sc); 511 } else { 512 if (j720tp_get_rawxy(sc, &rawx, &rawy)) 513 j720tp_wsmouse_input(sc, rawx, rawy); 514 callout_schedule(&sc->sc_tpcallout, hz / 32); 515 } 516 517 splx(s); 518 } 519 520 static void 521 j720tp_wskbd_input(struct j720tp_softc *sc, u_int evtype) 522 { 523 int key = j720tp_wskbd_keys[sc->sc_hard_icon - 1]; 524 525 #ifdef WSDISPLAY_COMPAT_RAWKBD 526 if (sc->sc_rawkbd) { 527 int n; 528 u_char data[16]; 529 530 n = pckbd_encode(evtype, key, data); 531 wskbd_rawinput(sc->sc_wskbddev, data, n); 532 } else 533 #endif 534 wskbd_input(sc->sc_wskbddev, evtype, key); 535 } 536 537 static void 538 j720tp_wskbd_callout(void *arg) 539 { 540 struct j720tp_softc *sc = arg; 541 struct j720ssp_softc *ssp = sc->sc_ssp; 542 int s; 543 544 s = spltty(); 545 546 if (!sc->sc_enabled) { 547 DPRINTF(("j720tp_wskbd_callout: !sc_enabled\n")); 548 splx(s); 549 return; 550 } 551 552 if (bus_space_read_4(ssp->sc_iot, ssp->sc_gpioh, SAGPIO_PLR) & (1<<9)) { 553 j720tp_wskbd_input(sc, WSCONS_EVENT_KEY_UP); 554 j720tp_enable_intr(sc); 555 } else { 556 callout_schedule(&sc->sc_tpcallout, hz / 32); 557 } 558 559 splx(s); 560 } 561 562 SYSCTL_SETUP(sysctl_j720tp, "sysctl j720tp subtree setup") 563 { 564 const struct sysctlnode *rnode; 565 int rc; 566 567 if ((rc = sysctl_createv(clog, 0, NULL, &rnode, 568 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL, 569 NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0) 570 goto err; 571 572 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 573 CTLFLAG_PERMANENT, CTLTYPE_NODE, "j720tp", 574 SYSCTL_DESCR("Jornada 720 touch panel controls"), 575 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 576 goto err; 577 578 #ifdef J720TP_DEBUG 579 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 580 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 581 SYSCTL_DESCR("Verbosity of debugging messages"), 582 NULL, 0, &j720tp_debug, 0, CTL_CREATE, CTL_EOL)) != 0) 583 goto err; 584 #endif /* J720TP_DEBUG */ 585 586 if ((rc = sysctl_createv(clog, 0, &rnode, &rnode, 587 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hard_icons", 588 SYSCTL_DESCR("Touch panel hard icons controls"), 589 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) 590 goto err; 591 592 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 593 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "left", 594 SYSCTL_DESCR("Raw left X value of the hard icon area"), 595 NULL, 0, &j720tp_hard_icon_left, 0, CTL_CREATE, CTL_EOL)) != 0) 596 goto err; 597 598 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 599 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "right", 600 SYSCTL_DESCR("Raw right X value of the hard icon area"), 601 NULL, 0, &j720tp_hard_icon_right, 0, CTL_CREATE, CTL_EOL)) != 0) 602 goto err; 603 604 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 605 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "top", 606 SYSCTL_DESCR("Raw top Y value of the hard icon area"), 607 NULL, 0, &j720tp_hard_icon_top, 0, CTL_CREATE, CTL_EOL)) != 0) 608 goto err; 609 610 if ((rc = sysctl_createv(clog, 0, &rnode, NULL, 611 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "bottom", 612 SYSCTL_DESCR("Raw bottom Y value of the hard icon area"), 613 NULL, 0, &j720tp_hard_icon_bottom, 0, CTL_CREATE, CTL_EOL)) != 0) 614 goto err; 615 616 return; 617 err: 618 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); 619 } 620