axp22x.c revision 1.3.2.2 1 1.3.2.2 jdolecek /* $NetBSD: axp22x.c,v 1.3.2.2 2017/12/03 11:37:02 jdolecek Exp $ */
2 1.3.2.2 jdolecek
3 1.3.2.2 jdolecek /*-
4 1.3.2.2 jdolecek * Copyright (c) 2014 Jared D. McNeill <jmcneill (at) invisible.ca>
5 1.3.2.2 jdolecek * All rights reserved.
6 1.3.2.2 jdolecek *
7 1.3.2.2 jdolecek * Redistribution and use in source and binary forms, with or without
8 1.3.2.2 jdolecek * modification, are permitted provided that the following conditions
9 1.3.2.2 jdolecek * are met:
10 1.3.2.2 jdolecek * 1. Redistributions of source code must retain the above copyright
11 1.3.2.2 jdolecek * notice, this list of conditions and the following disclaimer.
12 1.3.2.2 jdolecek * 2. Redistributions in binary form must reproduce the above copyright
13 1.3.2.2 jdolecek * notice, this list of conditions and the following disclaimer in the
14 1.3.2.2 jdolecek * documentation and/or other materials provided with the distribution.
15 1.3.2.2 jdolecek *
16 1.3.2.2 jdolecek * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.3.2.2 jdolecek * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.3.2.2 jdolecek * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.3.2.2 jdolecek * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.3.2.2 jdolecek * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.3.2.2 jdolecek * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.3.2.2 jdolecek * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.3.2.2 jdolecek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.3.2.2 jdolecek * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.3.2.2 jdolecek * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.3.2.2 jdolecek * POSSIBILITY OF SUCH DAMAGE.
27 1.3.2.2 jdolecek */
28 1.3.2.2 jdolecek
29 1.3.2.2 jdolecek #include <sys/cdefs.h>
30 1.3.2.2 jdolecek __KERNEL_RCSID(0, "$NetBSD: axp22x.c,v 1.3.2.2 2017/12/03 11:37:02 jdolecek Exp $");
31 1.3.2.2 jdolecek
32 1.3.2.2 jdolecek #include <sys/param.h>
33 1.3.2.2 jdolecek #include <sys/systm.h>
34 1.3.2.2 jdolecek #include <sys/device.h>
35 1.3.2.2 jdolecek #include <sys/conf.h>
36 1.3.2.2 jdolecek #include <sys/bus.h>
37 1.3.2.2 jdolecek #include <sys/kmem.h>
38 1.3.2.2 jdolecek
39 1.3.2.2 jdolecek #include <dev/i2c/i2cvar.h>
40 1.3.2.2 jdolecek
41 1.3.2.2 jdolecek #include <dev/sysmon/sysmonvar.h>
42 1.3.2.2 jdolecek
43 1.3.2.2 jdolecek static const char *compatible[] = {
44 1.3.2.2 jdolecek "x-powers,axp221",
45 1.3.2.2 jdolecek NULL
46 1.3.2.2 jdolecek };
47 1.3.2.2 jdolecek
48 1.3.2.2 jdolecek #define AXP_TEMP_MON_REG 0x56 /* 2 bytes */
49 1.3.2.2 jdolecek
50 1.3.2.2 jdolecek struct axp22x_softc {
51 1.3.2.2 jdolecek device_t sc_dev;
52 1.3.2.2 jdolecek i2c_tag_t sc_i2c;
53 1.3.2.2 jdolecek i2c_addr_t sc_addr;
54 1.3.2.2 jdolecek
55 1.3.2.2 jdolecek struct sysmon_envsys *sc_sme;
56 1.3.2.2 jdolecek envsys_data_t sc_sensor_temp;
57 1.3.2.2 jdolecek };
58 1.3.2.2 jdolecek
59 1.3.2.2 jdolecek static int axp22x_match(device_t, cfdata_t, void *);
60 1.3.2.2 jdolecek static void axp22x_attach(device_t, device_t, void *);
61 1.3.2.2 jdolecek
62 1.3.2.2 jdolecek static void axp22x_sensors_refresh(struct sysmon_envsys *, envsys_data_t *);
63 1.3.2.2 jdolecek static int axp22x_read(struct axp22x_softc *, uint8_t, uint8_t *, size_t);
64 1.3.2.2 jdolecek
65 1.3.2.2 jdolecek CFATTACH_DECL_NEW(axp22x, sizeof(struct axp22x_softc),
66 1.3.2.2 jdolecek axp22x_match, axp22x_attach, NULL, NULL);
67 1.3.2.2 jdolecek
68 1.3.2.2 jdolecek static int
69 1.3.2.2 jdolecek axp22x_match(device_t parent, cfdata_t match, void *aux)
70 1.3.2.2 jdolecek {
71 1.3.2.2 jdolecek struct i2c_attach_args *ia = aux;
72 1.3.2.2 jdolecek
73 1.3.2.2 jdolecek if (ia->ia_name != NULL)
74 1.3.2.2 jdolecek return iic_compat_match(ia, compatible);
75 1.3.2.2 jdolecek
76 1.3.2.2 jdolecek return 1;
77 1.3.2.2 jdolecek }
78 1.3.2.2 jdolecek
79 1.3.2.2 jdolecek static void
80 1.3.2.2 jdolecek axp22x_attach(device_t parent, device_t self, void *aux)
81 1.3.2.2 jdolecek {
82 1.3.2.2 jdolecek struct axp22x_softc *sc = device_private(self);
83 1.3.2.2 jdolecek struct i2c_attach_args *ia = aux;
84 1.3.2.2 jdolecek
85 1.3.2.2 jdolecek sc->sc_dev = self;
86 1.3.2.2 jdolecek sc->sc_i2c = ia->ia_tag;
87 1.3.2.2 jdolecek sc->sc_addr = ia->ia_addr;
88 1.3.2.2 jdolecek
89 1.3.2.2 jdolecek aprint_naive("\n");
90 1.3.2.2 jdolecek aprint_normal("\n");
91 1.3.2.2 jdolecek
92 1.3.2.2 jdolecek sc->sc_sme = sysmon_envsys_create();
93 1.3.2.2 jdolecek sc->sc_sme->sme_name = device_xname(self);
94 1.3.2.2 jdolecek sc->sc_sme->sme_cookie = sc;
95 1.3.2.2 jdolecek sc->sc_sme->sme_refresh = axp22x_sensors_refresh;
96 1.3.2.2 jdolecek
97 1.3.2.2 jdolecek sc->sc_sensor_temp.units = ENVSYS_STEMP;
98 1.3.2.2 jdolecek sc->sc_sensor_temp.state = ENVSYS_SINVALID;
99 1.3.2.2 jdolecek sc->sc_sensor_temp.flags = ENVSYS_FHAS_ENTROPY;
100 1.3.2.2 jdolecek snprintf(sc->sc_sensor_temp.desc, sizeof(sc->sc_sensor_temp.desc),
101 1.3.2.2 jdolecek "internal temperature");
102 1.3.2.2 jdolecek sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor_temp);
103 1.3.2.2 jdolecek
104 1.3.2.2 jdolecek sysmon_envsys_register(sc->sc_sme);
105 1.3.2.2 jdolecek }
106 1.3.2.2 jdolecek
107 1.3.2.2 jdolecek static void
108 1.3.2.2 jdolecek axp22x_sensors_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
109 1.3.2.2 jdolecek {
110 1.3.2.2 jdolecek struct axp22x_softc *sc = sme->sme_cookie;
111 1.3.2.2 jdolecek uint8_t buf[2];
112 1.3.2.2 jdolecek int error;
113 1.3.2.2 jdolecek
114 1.3.2.2 jdolecek iic_acquire_bus(sc->sc_i2c, 0);
115 1.3.2.2 jdolecek error = axp22x_read(sc, AXP_TEMP_MON_REG, buf, sizeof(buf));
116 1.3.2.2 jdolecek iic_release_bus(sc->sc_i2c, 0);
117 1.3.2.2 jdolecek
118 1.3.2.2 jdolecek if (error) {
119 1.3.2.2 jdolecek edata->state = ENVSYS_SINVALID;
120 1.3.2.2 jdolecek } else {
121 1.3.2.2 jdolecek /* between -243.7C and 165.8C, step +0.1C */
122 1.3.2.2 jdolecek edata->value_cur = (((buf[0] << 4) | (buf[1] & 0xf)) - 2437)
123 1.3.2.2 jdolecek * 100000 + 273150000;
124 1.3.2.2 jdolecek edata->state = ENVSYS_SVALID;
125 1.3.2.2 jdolecek }
126 1.3.2.2 jdolecek }
127 1.3.2.2 jdolecek
128 1.3.2.2 jdolecek static int
129 1.3.2.2 jdolecek axp22x_read(struct axp22x_softc *sc, uint8_t reg, uint8_t *val, size_t len)
130 1.3.2.2 jdolecek {
131 1.3.2.2 jdolecek size_t i;
132 1.3.2.2 jdolecek int error;
133 1.3.2.2 jdolecek
134 1.3.2.2 jdolecek for (i = 0; i < len; i++) {
135 1.3.2.2 jdolecek error = iic_smbus_read_byte(sc->sc_i2c, sc->sc_addr,
136 1.3.2.2 jdolecek reg + i, &val[i], 0);
137 1.3.2.2 jdolecek if (error)
138 1.3.2.2 jdolecek return error;
139 1.3.2.2 jdolecek }
140 1.3.2.2 jdolecek
141 1.3.2.2 jdolecek return 0;
142 1.3.2.2 jdolecek }
143