| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tps65217pmic.c,v 1.8 2014/01/08 16:45:14 jakllsch Exp $ */ | | 1 | /* $NetBSD: tps65217pmic.c,v 1.9 2014/01/08 16:49:48 jakllsch Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Radoslaw Kujawa. | | 8 | * by Radoslaw Kujawa. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -25,43 +25,43 @@ | | | @@ -25,43 +25,43 @@ |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Texas Instruments TPS65217 Power Management IC driver. | | 33 | * Texas Instruments TPS65217 Power Management IC driver. |
34 | * TODO: battery, sequencer, pgood | | 34 | * TODO: battery, sequencer, pgood |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.8 2014/01/08 16:45:14 jakllsch Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.9 2014/01/08 16:49:48 jakllsch Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/device.h> | | 42 | #include <sys/device.h> |
43 | #include <sys/kernel.h> | | 43 | #include <sys/kernel.h> |
44 | #include <sys/mutex.h> | | 44 | #include <sys/mutex.h> |
45 | | | 45 | |
46 | #include <sys/bus.h> | | 46 | #include <sys/bus.h> |
47 | #include <dev/i2c/i2cvar.h> | | 47 | #include <dev/i2c/i2cvar.h> |
48 | | | 48 | |
49 | #include <dev/sysmon/sysmonvar.h> | | 49 | #include <dev/sysmon/sysmonvar.h> |
50 | | | 50 | |
51 | #include <dev/i2c/tps65217pmicreg.h> | | 51 | #include <dev/i2c/tps65217pmicreg.h> |
52 | | | 52 | |
53 | #define NTPS_REG 7 | | 53 | #define NTPS_REG 7 |
54 | #define SNUM_REGS NTPS_REG-1 | | 54 | #define SNUM_REGS NTPS_REG-1 |
55 | #define SNUM_USBSTATUS NTPS_REG | | 55 | #define SNUM_USBSTATUS NTPS_REG |
56 | #define SNUM_ACSTATUS NTPS_REG+1 | | 56 | #define SNUM_ACSTATUS NTPS_REG+1 |
57 | | | 57 | |
58 | struct tps65217pmic_softc { | | 58 | struct tps65217pmic_softc { |
59 | device_t sc_dev; | | 59 | device_t sc_dev; |
60 | | | 60 | |
61 | i2c_tag_t sc_tag; | | 61 | i2c_tag_t sc_tag; |
62 | i2c_addr_t sc_addr; | | 62 | i2c_addr_t sc_addr; |
63 | | | 63 | |
64 | uint8_t sc_version; | | 64 | uint8_t sc_version; |
65 | uint8_t sc_revision; | | 65 | uint8_t sc_revision; |
66 | | | 66 | |
67 | kmutex_t sc_lock; | | 67 | kmutex_t sc_lock; |
| @@ -330,41 +330,41 @@ tps65217pmic_attach(device_t parent, dev | | | @@ -330,41 +330,41 @@ tps65217pmic_attach(device_t parent, dev |
330 | tps65217pmic_print_ppath(sc); | | 330 | tps65217pmic_print_ppath(sc); |
331 | tps65217pmic_print_ldos(sc); | | 331 | tps65217pmic_print_ldos(sc); |
332 | | | 332 | |
333 | tps65217pmic_power_monitor_init(sc); | | 333 | tps65217pmic_power_monitor_init(sc); |
334 | | | 334 | |
335 | tps65217pmic_envsys_register(sc); | | 335 | tps65217pmic_envsys_register(sc); |
336 | } | | 336 | } |
337 | | | 337 | |
338 | static void | | 338 | static void |
339 | tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc) | | 339 | tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc) |
340 | { | | 340 | { |
341 | uint8_t intr, intrmask, status, ppath; | | 341 | uint8_t intr, intrmask, status, ppath; |
342 | | | 342 | |
343 | intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM | | | 343 | intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM | |
344 | TPS65217PMIC_INT_PBM; | | 344 | TPS65217PMIC_INT_PBM; |
345 | | | 345 | |
346 | status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); | | 346 | status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); |
347 | ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); | | 347 | ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH); |
348 | /* acknowledge and disregard whatever interrupt was generated earlier */ | | 348 | /* acknowledge and disregard whatever interrupt was generated earlier */ |
349 | intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT); | | 349 | intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT); |
350 | | | 350 | |
351 | sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR; | | 351 | sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR; |
352 | sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR; | | 352 | sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR; |
353 | sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN; | | 353 | sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN; |
354 | sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN; | | 354 | sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN; |
355 | | | 355 | |
356 | if (intr & intrmask) | | 356 | if (intr & intrmask) |
357 | aprint_normal_dev(sc->sc_dev, | | 357 | aprint_normal_dev(sc->sc_dev, |
358 | "WARNING: hardware interrupt enabled but not supported"); | | 358 | "WARNING: hardware interrupt enabled but not supported"); |
359 | | | 359 | |
360 | /* set up callout to poll for power source changes */ | | 360 | /* set up callout to poll for power source changes */ |
361 | callout_init(&sc->sc_powerpollco, 0); | | 361 | callout_init(&sc->sc_powerpollco, 0); |
362 | callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc); | | 362 | callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc); |
363 | | | 363 | |
364 | callout_schedule(&sc->sc_powerpollco, hz); | | 364 | callout_schedule(&sc->sc_powerpollco, hz); |
365 | } | | 365 | } |
366 | | | 366 | |
367 | static void | | 367 | static void |
368 | tps65217pmic_power_monitor(void *aux) | | 368 | tps65217pmic_power_monitor(void *aux) |
369 | { | | 369 | { |
370 | struct tps65217pmic_softc *sc; | | 370 | struct tps65217pmic_softc *sc; |
| @@ -373,41 +373,41 @@ tps65217pmic_power_monitor(void *aux) | | | @@ -373,41 +373,41 @@ tps65217pmic_power_monitor(void *aux) |
373 | | | 373 | |
374 | sc = aux; | | 374 | sc = aux; |
375 | | | 375 | |
376 | mutex_enter(&sc->sc_lock); | | 376 | mutex_enter(&sc->sc_lock); |
377 | | | 377 | |
378 | status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); | | 378 | status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS); |
379 | usbstatus = status & TPS65217PMIC_STATUS_USBPWR; | | 379 | usbstatus = status & TPS65217PMIC_STATUS_USBPWR; |
380 | acstatus = status & TPS65217PMIC_STATUS_ACPWR; | | 380 | acstatus = status & TPS65217PMIC_STATUS_ACPWR; |
381 | | | 381 | |
382 | if (usbstatus != sc->sc_usbstatus) { | | 382 | if (usbstatus != sc->sc_usbstatus) { |
383 | sc->sc_usbstatus = usbstatus; | | 383 | sc->sc_usbstatus = usbstatus; |
384 | pmf_event_inject(NULL, PMFE_POWER_CHANGED); | | 384 | pmf_event_inject(NULL, PMFE_POWER_CHANGED); |
385 | if (usbstatus) | | 385 | if (usbstatus) |
386 | aprint_normal_dev(sc->sc_dev, | | 386 | aprint_normal_dev(sc->sc_dev, |
387 | "USB power source connected\n"); | | 387 | "USB power source connected\n"); |
388 | else | | 388 | else |
389 | aprint_normal_dev(sc->sc_dev, | | 389 | aprint_normal_dev(sc->sc_dev, |
390 | "USB power source disconnected\n"); | | 390 | "USB power source disconnected\n"); |
391 | } | | 391 | } |
392 | | | 392 | |
393 | if (acstatus != sc->sc_acstatus) { | | 393 | if (acstatus != sc->sc_acstatus) { |
394 | sc->sc_acstatus = acstatus; | | 394 | sc->sc_acstatus = acstatus; |
395 | pmf_event_inject(NULL, PMFE_POWER_CHANGED); | | 395 | pmf_event_inject(NULL, PMFE_POWER_CHANGED); |
396 | if (acstatus) { | | 396 | if (acstatus) { |
397 | sysmon_pswitch_event(&sc->sc_smpsw, | | 397 | sysmon_pswitch_event(&sc->sc_smpsw, |
398 | PSWITCH_EVENT_PRESSED); | | 398 | PSWITCH_EVENT_PRESSED); |
399 | } else { | | 399 | } else { |
400 | sysmon_pswitch_event(&sc->sc_smpsw, | | 400 | sysmon_pswitch_event(&sc->sc_smpsw, |
401 | PSWITCH_EVENT_RELEASED); | | 401 | PSWITCH_EVENT_RELEASED); |
402 | } | | 402 | } |
403 | } | | 403 | } |
404 | | | 404 | |
405 | mutex_exit(&sc->sc_lock); | | 405 | mutex_exit(&sc->sc_lock); |
406 | | | 406 | |
407 | callout_schedule(&sc->sc_powerpollco, hz); | | 407 | callout_schedule(&sc->sc_powerpollco, hz); |
408 | } | | 408 | } |
409 | | | 409 | |
410 | static void | | 410 | static void |
411 | tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc) | | 411 | tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc) |
412 | { | | 412 | { |
413 | int i; | | 413 | int i; |
| @@ -645,36 +645,36 @@ tps65217pmic_envsys_register(struct tps6 | | | @@ -645,36 +645,36 @@ tps65217pmic_envsys_register(struct tps6 |
645 | sizeof(sc->sc_regsensor[i].desc)); | | 645 | sizeof(sc->sc_regsensor[i].desc)); |
646 | sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC; | | 646 | sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC; |
647 | sc->sc_regsensor[i].state = ENVSYS_SINVALID; | | 647 | sc->sc_regsensor[i].state = ENVSYS_SINVALID; |
648 | | | 648 | |
649 | if (sysmon_envsys_sensor_attach(sc->sc_sme, | | 649 | if (sysmon_envsys_sensor_attach(sc->sc_sme, |
650 | &sc->sc_regsensor[i])) | | 650 | &sc->sc_regsensor[i])) |
651 | aprint_error_dev(sc->sc_dev, | | 651 | aprint_error_dev(sc->sc_dev, |
652 | "error attaching regulator sensor %d\n", i); | | 652 | "error attaching regulator sensor %d\n", i); |
653 | } | | 653 | } |
654 | | | 654 | |
655 | /* attach power source indicators */ | | 655 | /* attach power source indicators */ |
656 | strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */ | | 656 | strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */ |
657 | sc->sc_usbsensor.units = ENVSYS_INDICATOR; | | 657 | sc->sc_usbsensor.units = ENVSYS_INDICATOR; |
658 | sc->sc_usbsensor.state = ENVSYS_SINVALID; | | 658 | sc->sc_usbsensor.state = ENVSYS_SINVALID; |
659 | if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor)) | | 659 | if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor)) |
660 | aprint_error_dev(sc->sc_dev, | | 660 | aprint_error_dev(sc->sc_dev, |
661 | "error attaching USB power source sensor\n"); | | 661 | "error attaching USB power source sensor\n"); |
662 | strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */ | | 662 | strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */ |
663 | sc->sc_acsensor.units = ENVSYS_INDICATOR; | | 663 | sc->sc_acsensor.units = ENVSYS_INDICATOR; |
664 | sc->sc_acsensor.state = ENVSYS_SINVALID; | | 664 | sc->sc_acsensor.state = ENVSYS_SINVALID; |
665 | if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor)) | | 665 | if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor)) |
666 | aprint_error_dev(sc->sc_dev, | | 666 | aprint_error_dev(sc->sc_dev, |
667 | "error attaching AC power source sensor\n"); | | 667 | "error attaching AC power source sensor\n"); |
668 | | | 668 | |
669 | /* register everything in sysmon */ | | 669 | /* register everything in sysmon */ |
670 | sc->sc_sme->sme_name = device_xname(sc->sc_dev); | | 670 | sc->sc_sme->sme_name = device_xname(sc->sc_dev); |
671 | sc->sc_sme->sme_cookie = sc; | | 671 | sc->sc_sme->sme_cookie = sc; |
672 | sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh; | | 672 | sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh; |
673 | | | 673 | |
674 | if (sysmon_envsys_register(sc->sc_sme)) { | | 674 | if (sysmon_envsys_register(sc->sc_sme)) { |
675 | aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n"); | | 675 | aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n"); |
676 | sysmon_envsys_destroy(sc->sc_sme); | | 676 | sysmon_envsys_destroy(sc->sc_sme); |
677 | } | | 677 | } |
678 | } | | 678 | } |
679 | | | 679 | |
680 | static void | | 680 | static void |