Skip to content

Commit 790406c

Browse files
committed
Add Raspberry Pi PoE+ HAT support
Signed-off-by: Serge Schneider <[email protected]>
1 parent 58f672b commit 790406c

File tree

11 files changed

+285
-11
lines changed

11 files changed

+285
-11
lines changed

arch/arm/boot/dts/overlays/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
156156
rpi-display.dtbo \
157157
rpi-ft5406.dtbo \
158158
rpi-poe.dtbo \
159+
rpi-poe-plus.dtbo \
159160
rpi-proto.dtbo \
160161
rpi-sense.dtbo \
161162
rpi-tv.dtbo \
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2+
// Overlay for the Raspberry Pi PoE+ HAT.
3+
4+
#include "rpi-poe-overlay.dts"
5+
6+
/ {
7+
compatible = "brcm,bcm2835";
8+
9+
fragment@3 {
10+
target-path = "/";
11+
__overlay__ {
12+
rpi_poe_power_supply: rpi-poe-power-supply@0 {
13+
compatible = "raspberrypi,rpi-poe-power-supply";
14+
firmware = <&firmware>;
15+
status = "okay";
16+
};
17+
};
18+
};
19+
};

arch/arm/configs/bcm2709_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ CONFIG_W1_SLAVE_DS28E04=m
718718
CONFIG_W1_SLAVE_DS28E17=m
719719
CONFIG_POWER_RESET=y
720720
CONFIG_POWER_RESET_GPIO=y
721+
CONFIG_RPI_POE_POWER=m
721722
CONFIG_BATTERY_DS2760=m
722723
CONFIG_BATTERY_MAX17040=m
723724
CONFIG_BATTERY_GAUGE_LTC2941=m

arch/arm/configs/bcm2711_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ CONFIG_W1_SLAVE_DS28E04=m
731731
CONFIG_W1_SLAVE_DS28E17=m
732732
CONFIG_POWER_RESET=y
733733
CONFIG_POWER_RESET_GPIO=y
734+
CONFIG_RPI_POE_POWER=m
734735
CONFIG_BATTERY_DS2760=m
735736
CONFIG_BATTERY_MAX17040=m
736737
CONFIG_BATTERY_GAUGE_LTC2941=m

arch/arm/configs/bcmrpi_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,7 @@ CONFIG_W1_SLAVE_DS28E04=m
711711
CONFIG_W1_SLAVE_DS28E17=m
712712
CONFIG_POWER_RESET=y
713713
CONFIG_POWER_RESET_GPIO=y
714+
CONFIG_RPI_POE_POWER=m
714715
CONFIG_BATTERY_DS2760=m
715716
CONFIG_BATTERY_MAX17040=m
716717
CONFIG_BATTERY_GAUGE_LTC2941=m

arch/arm64/configs/bcm2711_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ CONFIG_W1_SLAVE_DS2781=m
724724
CONFIG_W1_SLAVE_DS28E04=m
725725
CONFIG_W1_SLAVE_DS28E17=m
726726
CONFIG_POWER_RESET_GPIO=y
727+
CONFIG_RPI_POE_POWER=m
727728
CONFIG_BATTERY_DS2760=m
728729
CONFIG_BATTERY_MAX17040=m
729730
CONFIG_BATTERY_GAUGE_LTC2941=m

drivers/hwmon/rpi-poe-fan.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
struct rpi_poe_fan_ctx {
2929
struct mutex lock;
3030
struct rpi_firmware *fw;
31+
u32 set_tag;
3132
unsigned int pwm_value;
3233
unsigned int def_pwm_value;
3334
unsigned int rpi_poe_fan_state;
@@ -43,13 +44,15 @@ struct fw_tag_data_s{
4344
u32 ret;
4445
};
4546

46-
static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val){
47+
static int write_reg(struct rpi_firmware *fw, u32 reg, u32 *val, u32 set_tag)
48+
{
4749
struct fw_tag_data_s fw_tag_data = {
4850
.reg = reg,
4951
.val = *val
5052
};
5153
int ret;
52-
ret = rpi_firmware_property(fw, RPI_FIRMWARE_SET_POE_HAT_VAL,
54+
55+
ret = rpi_firmware_property(fw, set_tag,
5356
&fw_tag_data, sizeof(fw_tag_data));
5457
if (ret) {
5558
return ret;
@@ -82,7 +85,7 @@ static int rpi_poe_reboot(struct notifier_block *nb, unsigned long code,
8285
nb);
8386

8487
if (ctx->pwm_value != ctx->def_pwm_value)
85-
write_reg(ctx->fw, POE_CUR_PWM, &ctx->def_pwm_value);
88+
write_reg(ctx->fw, POE_CUR_PWM, &ctx->def_pwm_value, ctx->set_tag);
8689

8790
return NOTIFY_DONE;
8891
}
@@ -95,7 +98,7 @@ static int __set_pwm(struct rpi_poe_fan_ctx *ctx, u32 pwm)
9598
if (ctx->pwm_value == pwm)
9699
goto exit_set_pwm_err;
97100

98-
ret = write_reg(ctx->fw, POE_CUR_PWM, &pwm);
101+
ret = write_reg(ctx->fw, POE_CUR_PWM, &pwm, ctx->set_tag);
99102
if (!ret)
100103
ctx->pwm_value = pwm;
101104
exit_set_pwm_err:
@@ -110,7 +113,7 @@ static int __set_def_pwm(struct rpi_poe_fan_ctx *ctx, u32 def_pwm)
110113
if (ctx->def_pwm_value == def_pwm)
111114
goto exit_set_def_pwm_err;
112115

113-
ret = write_reg(ctx->fw, POE_DEF_PWM, &def_pwm);
116+
ret = write_reg(ctx->fw, POE_DEF_PWM, &def_pwm, ctx->set_tag);
114117
if (!ret)
115118
ctx->def_pwm_value = def_pwm;
116119
exit_set_def_pwm_err:
@@ -297,6 +300,7 @@ static int rpi_poe_fan_probe(struct platform_device *pdev)
297300
struct device *hwmon;
298301
struct device_node *np = pdev->dev.of_node;
299302
struct device_node *fw_node;
303+
u32 revision;
300304
int ret;
301305

302306
fw_node = of_parse_phandle(np, "firmware", 0);
@@ -314,6 +318,17 @@ static int rpi_poe_fan_probe(struct platform_device *pdev)
314318
ctx->fw = rpi_firmware_get(fw_node);
315319
if (!ctx->fw)
316320
return -EPROBE_DEFER;
321+
ret = rpi_firmware_property(ctx->fw,
322+
RPI_FIRMWARE_GET_FIRMWARE_REVISION,
323+
&revision, sizeof(revision));
324+
if (ret) {
325+
dev_err(&pdev->dev, "Failed to get firmware revision: %i\n", ret);
326+
return ret;
327+
}
328+
if (revision < 0x60af72e8)
329+
ctx->set_tag = RPI_FIRMWARE_SET_POE_HAT_VAL_OLD;
330+
else
331+
ctx->set_tag = RPI_FIRMWARE_SET_POE_HAT_VAL;
317332

318333
platform_set_drvdata(pdev, ctx);
319334

@@ -378,9 +393,9 @@ static int rpi_poe_fan_remove(struct platform_device *pdev)
378393

379394
unregister_reboot_notifier(&ctx->nb);
380395
thermal_cooling_device_unregister(ctx->cdev);
381-
if (ctx->pwm_value != value) {
382-
write_reg(ctx->fw, POE_CUR_PWM, &value);
383-
}
396+
if (ctx->pwm_value != value)
397+
write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
398+
384399
return 0;
385400
}
386401

@@ -392,7 +407,7 @@ static int rpi_poe_fan_suspend(struct device *dev)
392407
int ret = 0;
393408

394409
if (ctx->pwm_value != value)
395-
ret = write_reg(ctx->fw, POE_CUR_PWM, &value);
410+
ret = write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
396411
return ret;
397412
}
398413

@@ -403,7 +418,7 @@ static int rpi_poe_fan_resume(struct device *dev)
403418
int ret = 0;
404419

405420
if (value != 0)
406-
ret = write_reg(ctx->fw, POE_CUR_PWM, &value);
421+
ret = write_reg(ctx->fw, POE_CUR_PWM, &value, ctx->set_tag);
407422

408423
return ret;
409424
}

drivers/power/supply/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ config POWER_SUPPLY_HWMON
2828
Say 'Y' here if you want power supplies to
2929
have hwmon sysfs interface too.
3030

31+
config RPI_POE_POWER
32+
tristate "Raspberry Pi PoE+ HAT power supply driver"
33+
depends on RASPBERRYPI_FIRMWARE
34+
help
35+
Say Y here to enable support for Raspberry Pi PoE+ (Power over Ethernet
36+
Plus) HAT current measurement.
3137

3238
config PDA_POWER
3339
tristate "Generic PDA/phone power driver"

drivers/power/supply/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
99
obj-$(CONFIG_POWER_SUPPLY_HWMON) += power_supply_hwmon.o
1010
obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
1111

12+
obj-$(CONFIG_RPI_POE_POWER) += rpi_poe_power.o
1213
obj-$(CONFIG_PDA_POWER) += pda_power.o
1314
obj-$(CONFIG_APM_POWER) += apm_power.o
1415
obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o

0 commit comments

Comments
 (0)