1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2021 Nicolas Saenz Julienne <nsaenzjulienne@suse.de> 4 * For more information on Raspberry Pi's PoE hat see: 5 * https://www.raspberrypi.org/products/poe-hat/ 6 * 7 * Limitations: 8 * - No disable bit, so a disabled PWM is simulated by duty_cycle 0 9 * - Only normal polarity 10 * - Fixed 12.5 kHz period 11 * 12 * The current period is completed when HW is reconfigured. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/pwm.h> 19 20 #include <soc/bcm2835/raspberrypi-firmware.h> 21 #include <dt-bindings/pwm/raspberrypi,firmware-poe-pwm.h> 22 23 #define RPI_PWM_MAX_DUTY 255 24 #define RPI_PWM_PERIOD_NS 80000 /* 12.5 kHz */ 25 26 #define RPI_PWM_CUR_DUTY_REG 0x0 27 28 struct raspberrypi_pwm { 29 struct rpi_firmware *firmware; 30 unsigned int duty_cycle; 31 }; 32 33 struct raspberrypi_pwm_prop { 34 __le32 reg; 35 __le32 val; 36 __le32 ret; 37 } __packed; 38 39 static inline 40 struct raspberrypi_pwm *raspberrypi_pwm_from_chip(struct pwm_chip *chip) 41 { 42 return pwmchip_get_drvdata(chip); 43 } 44 45 static int raspberrypi_pwm_set_property(struct rpi_firmware *firmware, 46 u32 reg, u32 val) 47 { 48 struct raspberrypi_pwm_prop msg = { 49 .reg = cpu_to_le32(reg), 50 .val = cpu_to_le32(val), 51 }; 52 int ret; 53 54 ret = rpi_firmware_property(firmware, RPI_FIRMWARE_SET_POE_HAT_VAL, 55 &msg, sizeof(msg)); 56 if (ret) 57 return ret; 58 if (msg.ret) 59 return -EIO; 60 61 return 0; 62 } 63 64 static int raspberrypi_pwm_get_property(struct rpi_firmware *firmware, 65 u32 reg, u32 *val) 66 { 67 struct raspberrypi_pwm_prop msg = { 68 .reg = cpu_to_le32(reg), 69 }; 70 int ret; 71 72 ret = rpi_firmware_property(firmware, RPI_FIRMWARE_GET_POE_HAT_VAL, 73 &msg, sizeof(msg)); 74 if (ret) 75 return ret; 76 if (msg.ret) 77 return -EIO; 78 79 *val = le32_to_cpu(msg.val); 80 81 return 0; 82 } 83 84 static int raspberrypi_pwm_get_state(struct pwm_chip *chip, 85 struct pwm_device *pwm, 86 struct pwm_state *state) 87 { 88 struct raspberrypi_pwm *rpipwm = raspberrypi_pwm_from_chip(chip); 89 90 state->period = RPI_PWM_PERIOD_NS; 91 state->duty_cycle = DIV_ROUND_UP(rpipwm->duty_cycle * RPI_PWM_PERIOD_NS, 92 RPI_PWM_MAX_DUTY); 93 state->enabled = !!(rpipwm->duty_cycle); 94 state->polarity = PWM_POLARITY_NORMAL; 95 96 return 0; 97 } 98 99 static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 100 const struct pwm_state *state) 101 { 102 struct raspberrypi_pwm *rpipwm = raspberrypi_pwm_from_chip(chip); 103 unsigned int duty_cycle; 104 int ret; 105 106 if (state->period < RPI_PWM_PERIOD_NS || 107 state->polarity != PWM_POLARITY_NORMAL) 108 return -EINVAL; 109 110 if (!state->enabled) 111 duty_cycle = 0; 112 else if (state->duty_cycle < RPI_PWM_PERIOD_NS) 113 duty_cycle = DIV_ROUND_DOWN_ULL(state->duty_cycle * RPI_PWM_MAX_DUTY, 114 RPI_PWM_PERIOD_NS); 115 else 116 duty_cycle = RPI_PWM_MAX_DUTY; 117 118 if (duty_cycle == rpipwm->duty_cycle) 119 return 0; 120 121 ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG, 122 duty_cycle); 123 if (ret) { 124 dev_err(pwmchip_parent(chip), "Failed to set duty cycle: %pe\n", 125 ERR_PTR(ret)); 126 return ret; 127 } 128 129 rpipwm->duty_cycle = duty_cycle; 130 131 return 0; 132 } 133 134 static const struct pwm_ops raspberrypi_pwm_ops = { 135 .get_state = raspberrypi_pwm_get_state, 136 .apply = raspberrypi_pwm_apply, 137 }; 138 139 static int raspberrypi_pwm_probe(struct platform_device *pdev) 140 { 141 struct device_node *firmware_node; 142 struct device *dev = &pdev->dev; 143 struct rpi_firmware *firmware; 144 struct pwm_chip *chip; 145 struct raspberrypi_pwm *rpipwm; 146 int ret; 147 148 firmware_node = of_get_parent(dev->of_node); 149 if (!firmware_node) { 150 dev_err(dev, "Missing firmware node\n"); 151 return -ENOENT; 152 } 153 154 firmware = devm_rpi_firmware_get(&pdev->dev, firmware_node); 155 of_node_put(firmware_node); 156 if (!firmware) 157 return dev_err_probe(dev, -EPROBE_DEFER, 158 "Failed to get firmware handle\n"); 159 160 chip = devm_pwmchip_alloc(&pdev->dev, RASPBERRYPI_FIRMWARE_PWM_NUM, 161 sizeof(*rpipwm)); 162 if (IS_ERR(chip)) 163 return PTR_ERR(chip); 164 rpipwm = raspberrypi_pwm_from_chip(chip); 165 166 rpipwm->firmware = firmware; 167 chip->ops = &raspberrypi_pwm_ops; 168 169 ret = raspberrypi_pwm_get_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG, 170 &rpipwm->duty_cycle); 171 if (ret) { 172 dev_err(dev, "Failed to get duty cycle: %pe\n", ERR_PTR(ret)); 173 return ret; 174 } 175 176 return devm_pwmchip_add(dev, chip); 177 } 178 179 static const struct of_device_id raspberrypi_pwm_of_match[] = { 180 { .compatible = "raspberrypi,firmware-poe-pwm", }, 181 { } 182 }; 183 MODULE_DEVICE_TABLE(of, raspberrypi_pwm_of_match); 184 185 static struct platform_driver raspberrypi_pwm_driver = { 186 .driver = { 187 .name = "raspberrypi-poe-pwm", 188 .of_match_table = raspberrypi_pwm_of_match, 189 }, 190 .probe = raspberrypi_pwm_probe, 191 }; 192 module_platform_driver(raspberrypi_pwm_driver); 193 194 MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>"); 195 MODULE_DESCRIPTION("Raspberry Pi Firmware Based PWM Bus Driver"); 196 MODULE_LICENSE("GPL v2"); 197