swsensor.c revision 1.1 1 /* $NetBSD: swsensor.c,v 1.1 2010/10/19 11:55:38 pgoyette Exp $ */
2 /*
3 * Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
16 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: swsensor.c,v 1.1 2010/10/19 11:55:38 pgoyette Exp $");
31
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/sysctl.h>
36
37 #include <dev/sysmon/sysmonvar.h>
38
39 #include <prop/proplib.h>
40
41 int swsensorattach(int);
42
43 static struct sysctllog *swsensor_sysctllog = NULL;
44
45 static int sensor_value_sysctl = 0;
46
47 static struct sysmon_envsys *swsensor_sme;
48 static envsys_data_t swsensor_edata;
49
50 static int32_t sw_sensor_value;
51
52 MODULE(MODULE_CLASS_DRIVER, swsensor, NULL);
53
54 /*
55 * Set-up the sysctl interface for setting the sensor's cur_value
56 */
57
58 static
59 void
60 sysctl_swsensor_setup(void)
61 {
62 int ret;
63 int node_sysctl_num;
64 const struct sysctlnode *me = NULL;
65
66 KASSERT(swsensor_sysctllog == NULL);
67
68 ret = sysctl_createv(&swsensor_sysctllog, 0, NULL, &me,
69 CTLFLAG_READWRITE,
70 CTLTYPE_NODE, "swsensor", NULL,
71 NULL, 0, NULL, 0,
72 CTL_HW, CTL_CREATE, CTL_EOL);
73 if (ret != 0)
74 return;
75
76 node_sysctl_num = me->sysctl_num;
77 ret = sysctl_createv(&swsensor_sysctllog, 0, NULL, &me,
78 CTLFLAG_READWRITE,
79 CTLTYPE_INT, "cur_value", NULL,
80 NULL, 0, &sw_sensor_value, 0,
81 CTL_HW, node_sysctl_num, CTL_CREATE, CTL_EOL);
82
83 if (ret == 0)
84 sensor_value_sysctl = me->sysctl_num;
85 }
86
87 /*
88 * "Polling" routine to update sensor value
89 */
90 static
91 void
92 swsensor_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
93 {
94
95 edata->value_cur = sw_sensor_value;
96 }
97
98 /*
99 * Module management
100 */
101
102 static
103 int
104 swsensor_init(void *arg)
105 {
106 int error;
107 prop_dictionary_t pd = (prop_dictionary_t)arg;
108 prop_object_t po = NULL;
109 int pv;
110
111 swsensor_sme = sysmon_envsys_create();
112 if (swsensor_sme == NULL)
113 return ENOTTY;
114
115 swsensor_sme->sme_name = "swsensor";
116 swsensor_sme->sme_cookie = &swsensor_edata;
117 swsensor_sme->sme_refresh = swsensor_refresh;
118 swsensor_sme->sme_set_limits = NULL;
119 swsensor_sme->sme_get_limits = NULL;
120
121 /* See if prop dictionary supplies a sensor type */
122 if (pd != NULL)
123 po = prop_dictionary_get(pd, "type");
124
125 pv = -1;
126 if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
127 swsensor_edata.units = prop_number_integer_value(po);
128 else
129 swsensor_edata.units = ENVSYS_INTEGER;
130
131 /* See if prop dictionary supplies sensor flags */
132 if (pd != NULL)
133 po = prop_dictionary_get(pd, "flags");
134
135 pv = -1;
136 if (po != NULL && prop_object_type(po) == PROP_TYPE_NUMBER)
137 swsensor_edata.flags = prop_number_integer_value(po);
138 else
139 swsensor_edata.flags = 0;
140
141 swsensor_edata.value_cur = 0;
142 strlcpy(swsensor_edata.desc, "sensor", ENVSYS_DESCLEN);
143
144 error = sysmon_envsys_sensor_attach(swsensor_sme, &swsensor_edata);
145
146 if (error == 0)
147 error = sysmon_envsys_register(swsensor_sme);
148 else {
149 printf("sysmon_envsys_sensor_attach failed: %d\n", error);
150 return error;
151 }
152
153 if (error == 0)
154 sysctl_swsensor_setup();
155 else
156 printf("sysmon_envsys_register failed: %d\n", error);
157
158 return error;
159 }
160
161 static
162 int
163 swsensor_fini(void *arg)
164 {
165
166 sysmon_envsys_unregister(swsensor_sme);
167
168 sysctl_teardown(&swsensor_sysctllog);
169
170 return 0;
171 }
172
173 static
174 int
175 swsensor_modcmd(modcmd_t cmd, void *arg)
176 {
177 int ret;
178
179 switch (cmd) {
180 case MODULE_CMD_INIT:
181 ret = swsensor_init(arg);
182 break;
183
184 case MODULE_CMD_FINI:
185 ret = swsensor_fini(arg);
186 break;
187
188 case MODULE_CMD_STAT:
189 default:
190 ret = ENOTTY;
191 }
192
193 return ret;
194 }
195
196 /*
197 * Initialization entry for rump
198 */
199
200 int
201 swsensorattach(int n __unused)
202 {
203 printf("%s: ", "swsensor0");
204
205 return swsensor_init(NULL);
206 }
207