pwm.c (7705B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * PWM Greybus driver. 4 * 5 * Copyright 2014 Google Inc. 6 * Copyright 2014 Linaro Ltd. 7 */ 8 9#include <linux/kernel.h> 10#include <linux/module.h> 11#include <linux/slab.h> 12#include <linux/pwm.h> 13#include <linux/greybus.h> 14 15#include "gbphy.h" 16 17struct gb_pwm_chip { 18 struct gb_connection *connection; 19 u8 pwm_max; /* max pwm number */ 20 21 struct pwm_chip chip; 22 struct pwm_chip *pwm; 23}; 24#define pwm_chip_to_gb_pwm_chip(chip) \ 25 container_of(chip, struct gb_pwm_chip, chip) 26 27 28static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc) 29{ 30 struct gb_pwm_count_response response; 31 int ret; 32 33 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_PWM_COUNT, 34 NULL, 0, &response, sizeof(response)); 35 if (ret) 36 return ret; 37 pwmc->pwm_max = response.count; 38 return 0; 39} 40 41static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc, 42 u8 which) 43{ 44 struct gb_pwm_activate_request request; 45 struct gbphy_device *gbphy_dev; 46 int ret; 47 48 if (which > pwmc->pwm_max) 49 return -EINVAL; 50 51 request.which = which; 52 53 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 54 ret = gbphy_runtime_get_sync(gbphy_dev); 55 if (ret) 56 return ret; 57 58 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ACTIVATE, 59 &request, sizeof(request), NULL, 0); 60 61 gbphy_runtime_put_autosuspend(gbphy_dev); 62 63 return ret; 64} 65 66static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc, 67 u8 which) 68{ 69 struct gb_pwm_deactivate_request request; 70 struct gbphy_device *gbphy_dev; 71 int ret; 72 73 if (which > pwmc->pwm_max) 74 return -EINVAL; 75 76 request.which = which; 77 78 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 79 ret = gbphy_runtime_get_sync(gbphy_dev); 80 if (ret) 81 return ret; 82 83 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DEACTIVATE, 84 &request, sizeof(request), NULL, 0); 85 86 gbphy_runtime_put_autosuspend(gbphy_dev); 87 88 return ret; 89} 90 91static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc, 92 u8 which, u32 duty, u32 period) 93{ 94 struct gb_pwm_config_request request; 95 struct gbphy_device *gbphy_dev; 96 int ret; 97 98 if (which > pwmc->pwm_max) 99 return -EINVAL; 100 101 request.which = which; 102 request.duty = cpu_to_le32(duty); 103 request.period = cpu_to_le32(period); 104 105 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 106 ret = gbphy_runtime_get_sync(gbphy_dev); 107 if (ret) 108 return ret; 109 110 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_CONFIG, 111 &request, sizeof(request), NULL, 0); 112 113 gbphy_runtime_put_autosuspend(gbphy_dev); 114 115 return ret; 116} 117 118static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc, 119 u8 which, u8 polarity) 120{ 121 struct gb_pwm_polarity_request request; 122 struct gbphy_device *gbphy_dev; 123 int ret; 124 125 if (which > pwmc->pwm_max) 126 return -EINVAL; 127 128 request.which = which; 129 request.polarity = polarity; 130 131 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 132 ret = gbphy_runtime_get_sync(gbphy_dev); 133 if (ret) 134 return ret; 135 136 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_POLARITY, 137 &request, sizeof(request), NULL, 0); 138 139 gbphy_runtime_put_autosuspend(gbphy_dev); 140 141 return ret; 142} 143 144static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc, 145 u8 which) 146{ 147 struct gb_pwm_enable_request request; 148 struct gbphy_device *gbphy_dev; 149 int ret; 150 151 if (which > pwmc->pwm_max) 152 return -EINVAL; 153 154 request.which = which; 155 156 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 157 ret = gbphy_runtime_get_sync(gbphy_dev); 158 if (ret) 159 return ret; 160 161 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ENABLE, 162 &request, sizeof(request), NULL, 0); 163 if (ret) 164 gbphy_runtime_put_autosuspend(gbphy_dev); 165 166 return ret; 167} 168 169static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc, 170 u8 which) 171{ 172 struct gb_pwm_disable_request request; 173 struct gbphy_device *gbphy_dev; 174 int ret; 175 176 if (which > pwmc->pwm_max) 177 return -EINVAL; 178 179 request.which = which; 180 181 ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DISABLE, 182 &request, sizeof(request), NULL, 0); 183 184 gbphy_dev = to_gbphy_dev(pwmc->chip.dev); 185 gbphy_runtime_put_autosuspend(gbphy_dev); 186 187 return ret; 188} 189 190static int gb_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) 191{ 192 struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); 193 194 return gb_pwm_activate_operation(pwmc, pwm->hwpwm); 195}; 196 197static void gb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 198{ 199 struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); 200 201 if (pwm_is_enabled(pwm)) 202 dev_warn(chip->dev, "freeing PWM device without disabling\n"); 203 204 gb_pwm_deactivate_operation(pwmc, pwm->hwpwm); 205} 206 207static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 208 const struct pwm_state *state) 209{ 210 int err; 211 bool enabled = pwm->state.enabled; 212 u64 period = state->period; 213 u64 duty_cycle = state->duty_cycle; 214 struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip); 215 216 /* Set polarity */ 217 if (state->polarity != pwm->state.polarity) { 218 if (enabled) { 219 gb_pwm_disable_operation(pwmc, pwm->hwpwm); 220 enabled = false; 221 } 222 err = gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, state->polarity); 223 if (err) 224 return err; 225 } 226 227 if (!state->enabled) { 228 if (enabled) 229 gb_pwm_disable_operation(pwmc, pwm->hwpwm); 230 return 0; 231 } 232 233 /* 234 * Set period and duty cycle 235 * 236 * PWM privodes 64-bit period and duty_cycle, but greybus only accepts 237 * 32-bit, so their values have to be limited to U32_MAX. 238 */ 239 if (period > U32_MAX) 240 period = U32_MAX; 241 242 if (duty_cycle > period) 243 duty_cycle = period; 244 245 err = gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_cycle, period); 246 if (err) 247 return err; 248 249 /* enable/disable */ 250 if (!enabled) 251 return gb_pwm_enable_operation(pwmc, pwm->hwpwm); 252 253 return 0; 254} 255 256static const struct pwm_ops gb_pwm_ops = { 257 .request = gb_pwm_request, 258 .free = gb_pwm_free, 259 .apply = gb_pwm_apply, 260 .owner = THIS_MODULE, 261}; 262 263static int gb_pwm_probe(struct gbphy_device *gbphy_dev, 264 const struct gbphy_device_id *id) 265{ 266 struct gb_connection *connection; 267 struct gb_pwm_chip *pwmc; 268 struct pwm_chip *pwm; 269 int ret; 270 271 pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL); 272 if (!pwmc) 273 return -ENOMEM; 274 275 connection = gb_connection_create(gbphy_dev->bundle, 276 le16_to_cpu(gbphy_dev->cport_desc->id), 277 NULL); 278 if (IS_ERR(connection)) { 279 ret = PTR_ERR(connection); 280 goto exit_pwmc_free; 281 } 282 283 pwmc->connection = connection; 284 gb_connection_set_data(connection, pwmc); 285 gb_gbphy_set_data(gbphy_dev, pwmc); 286 287 ret = gb_connection_enable(connection); 288 if (ret) 289 goto exit_connection_destroy; 290 291 /* Query number of pwms present */ 292 ret = gb_pwm_count_operation(pwmc); 293 if (ret) 294 goto exit_connection_disable; 295 296 pwm = &pwmc->chip; 297 298 pwm->dev = &gbphy_dev->dev; 299 pwm->ops = &gb_pwm_ops; 300 pwm->npwm = pwmc->pwm_max + 1; 301 302 ret = pwmchip_add(pwm); 303 if (ret) { 304 dev_err(&gbphy_dev->dev, 305 "failed to register PWM: %d\n", ret); 306 goto exit_connection_disable; 307 } 308 309 gbphy_runtime_put_autosuspend(gbphy_dev); 310 return 0; 311 312exit_connection_disable: 313 gb_connection_disable(connection); 314exit_connection_destroy: 315 gb_connection_destroy(connection); 316exit_pwmc_free: 317 kfree(pwmc); 318 return ret; 319} 320 321static void gb_pwm_remove(struct gbphy_device *gbphy_dev) 322{ 323 struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev); 324 struct gb_connection *connection = pwmc->connection; 325 int ret; 326 327 ret = gbphy_runtime_get_sync(gbphy_dev); 328 if (ret) 329 gbphy_runtime_get_noresume(gbphy_dev); 330 331 pwmchip_remove(&pwmc->chip); 332 gb_connection_disable(connection); 333 gb_connection_destroy(connection); 334 kfree(pwmc); 335} 336 337static const struct gbphy_device_id gb_pwm_id_table[] = { 338 { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) }, 339 { }, 340}; 341MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table); 342 343static struct gbphy_driver pwm_driver = { 344 .name = "pwm", 345 .probe = gb_pwm_probe, 346 .remove = gb_pwm_remove, 347 .id_table = gb_pwm_id_table, 348}; 349 350module_gbphy_driver(pwm_driver); 351MODULE_LICENSE("GPL v2");