10 #include <linux/types.h>
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
14 #include <linux/slab.h>
16 #include <linux/wait.h>
19 #include <asm/machdep.h>
21 #include <asm/sections.h>
31 #define DBG(args...) printk(args)
33 #define DBG(args...) do { } while(0)
41 static int cpuvcp_version;
44 static u8 *debugswitches;
57 #define to_smu_ads(c) container_of(c, struct smu_ad_sensor, sens)
68 struct smu_simple_cmd
cmd;
77 if (
cmd.cmd.status != 0)
78 return cmd.cmd.status;
79 if (
cmd.cmd.reply_len != 2) {
81 id,
cmd.cmd.reply_len);
84 *value = *((
u16 *)
cmd.buffer);
95 rc = smu_read_adc(ads->
reg, &val);
106 *value = (
s32)(scaled << 1);
111 static int smu_cpuamp_get(
struct wf_sensor *sr,
s32 *value)
117 rc = smu_read_adc(ads->
reg, &val);
127 *value = scaled << 4;
132 static int smu_cpuvolt_get(
struct wf_sensor *sr,
s32 *value)
138 rc = smu_read_adc(ads->
reg, &val);
148 *value = scaled << 4;
153 static int smu_slotspow_get(
struct wf_sensor *sr,
s32 *value)
159 rc = smu_read_adc(ads->
reg, &val);
169 *value = scaled << 4;
176 .get_value = smu_cputemp_get,
177 .release = smu_ads_release,
181 .get_value = smu_cpuamp_get,
182 .release = smu_ads_release,
186 .get_value = smu_cpuvolt_get,
187 .release = smu_ads_release,
191 .get_value = smu_slotspow_get,
192 .release = smu_ads_release,
218 if (!
strcmp(c,
"temp-sensor") &&
219 !
strcmp(l,
"CPU T-Diode")) {
220 ads->
sens.ops = &smu_cputemp_ops;
221 ads->
sens.name =
"cpu-temp";
222 if (cpudiode ==
NULL) {
223 DBG(
"wf: cpudiode partition (%02x) not found\n",
227 }
else if (!
strcmp(c,
"current-sensor") &&
228 !
strcmp(l,
"CPU Current")) {
229 ads->
sens.ops = &smu_cpuamp_ops;
230 ads->
sens.name =
"cpu-current";
231 if (cpuvcp ==
NULL) {
232 DBG(
"wf: cpuvcp partition (%02x) not found\n",
236 }
else if (!
strcmp(c,
"voltage-sensor") &&
237 !
strcmp(l,
"CPU Voltage")) {
238 ads->
sens.ops = &smu_cpuvolt_ops;
239 ads->
sens.name =
"cpu-voltage";
240 if (cpuvcp ==
NULL) {
241 DBG(
"wf: cpuvcp partition (%02x) not found\n",
245 }
else if (!
strcmp(c,
"power-sensor") &&
246 !
strcmp(l,
"Slots Power")) {
247 ads->
sens.ops = &smu_slotspow_ops;
248 ads->
sens.name =
"slots-power";
249 if (slotspow ==
NULL) {
250 DBG(
"wf: slotspow partition (%02x) not found\n",
282 #define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)
286 static void smu_cpu_power_release(
struct wf_sensor *sr)
297 static int smu_cpu_power_get(
struct wf_sensor *sr,
s32 *value)
301 u64 tmps, tmpa, tmpb;
304 rc = pow->
amps->ops->get_value(pow->
amps, &s);
309 *value = amps * 12 - 0x30000;
313 rc = pow->
volts->ops->get_value(pow->
volts, &volts);
317 power = (
s32)((((
u64)volts) * ((
u64)amps)) >> 16);
322 tmps = (((
u64)power) * ((
u64)power)) >> 16;
325 *value = (tmpa >> 28) + (tmpb >> 28) + (cpuvcp->
power_quads[2] >> 12);
331 .get_value = smu_cpu_power_get,
332 .release = smu_cpu_power_release,
345 pow->
sens.ops = &smu_cpu_power_ops;
346 pow->
sens.name =
"cpu-power";
354 if (debugswitches && ((*debugswitches) & 0x80)) {
368 cpuvcp_version >= 2) {
370 DBG(
"windfarm: CPU Power using quadratic transform\n");
382 static void smu_fetch_param_partitions(
void)
407 debugswitches = (
u8 *)&hdr[1];
410 static int __init smu_sensors_init(
void)
419 smu_fetch_param_partitions();
438 ads = smu_ads_create(s);
441 list_add(&ads->
link, &smu_ads);
445 else if (!
strcmp(ads->
sens.name,
"cpu-current"))
449 of_node_put(sensors);
452 if (volt_sensor && curr_sensor)
453 smu_cpu_power = smu_cpu_power_create(&volt_sensor->
sens,
459 static void __exit smu_sensors_exit(
void)
468 while (!list_empty(&smu_ads)) {