root/drivers/staging/greybus/pwm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gb_pwm_count_operation
  2. gb_pwm_activate_operation
  3. gb_pwm_deactivate_operation
  4. gb_pwm_config_operation
  5. gb_pwm_set_polarity_operation
  6. gb_pwm_enable_operation
  7. gb_pwm_disable_operation
  8. gb_pwm_request
  9. gb_pwm_free
  10. gb_pwm_config
  11. gb_pwm_set_polarity
  12. gb_pwm_enable
  13. gb_pwm_disable
  14. gb_pwm_probe
  15. gb_pwm_remove

   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 
  17 struct 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 
  28 static 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 
  41 static 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 
  66 static 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 
  91 static 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 
 118 static 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 
 144 static 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 
 169 static 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 
 190 static 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 
 197 static 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 
 207 static int gb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 208                          int duty_ns, int period_ns)
 209 {
 210         struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
 211 
 212         return gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_ns, period_ns);
 213 };
 214 
 215 static int gb_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 216                                enum pwm_polarity polarity)
 217 {
 218         struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
 219 
 220         return gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, polarity);
 221 };
 222 
 223 static int gb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 224 {
 225         struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
 226 
 227         return gb_pwm_enable_operation(pwmc, pwm->hwpwm);
 228 };
 229 
 230 static void gb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 231 {
 232         struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
 233 
 234         gb_pwm_disable_operation(pwmc, pwm->hwpwm);
 235 };
 236 
 237 static const struct pwm_ops gb_pwm_ops = {
 238         .request = gb_pwm_request,
 239         .free = gb_pwm_free,
 240         .config = gb_pwm_config,
 241         .set_polarity = gb_pwm_set_polarity,
 242         .enable = gb_pwm_enable,
 243         .disable = gb_pwm_disable,
 244         .owner = THIS_MODULE,
 245 };
 246 
 247 static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
 248                         const struct gbphy_device_id *id)
 249 {
 250         struct gb_connection *connection;
 251         struct gb_pwm_chip *pwmc;
 252         struct pwm_chip *pwm;
 253         int ret;
 254 
 255         pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
 256         if (!pwmc)
 257                 return -ENOMEM;
 258 
 259         connection = gb_connection_create(gbphy_dev->bundle,
 260                                           le16_to_cpu(gbphy_dev->cport_desc->id),
 261                                           NULL);
 262         if (IS_ERR(connection)) {
 263                 ret = PTR_ERR(connection);
 264                 goto exit_pwmc_free;
 265         }
 266 
 267         pwmc->connection = connection;
 268         gb_connection_set_data(connection, pwmc);
 269         gb_gbphy_set_data(gbphy_dev, pwmc);
 270 
 271         ret = gb_connection_enable(connection);
 272         if (ret)
 273                 goto exit_connection_destroy;
 274 
 275         /* Query number of pwms present */
 276         ret = gb_pwm_count_operation(pwmc);
 277         if (ret)
 278                 goto exit_connection_disable;
 279 
 280         pwm = &pwmc->chip;
 281 
 282         pwm->dev = &gbphy_dev->dev;
 283         pwm->ops = &gb_pwm_ops;
 284         pwm->base = -1;                 /* Allocate base dynamically */
 285         pwm->npwm = pwmc->pwm_max + 1;
 286 
 287         ret = pwmchip_add(pwm);
 288         if (ret) {
 289                 dev_err(&gbphy_dev->dev,
 290                         "failed to register PWM: %d\n", ret);
 291                 goto exit_connection_disable;
 292         }
 293 
 294         gbphy_runtime_put_autosuspend(gbphy_dev);
 295         return 0;
 296 
 297 exit_connection_disable:
 298         gb_connection_disable(connection);
 299 exit_connection_destroy:
 300         gb_connection_destroy(connection);
 301 exit_pwmc_free:
 302         kfree(pwmc);
 303         return ret;
 304 }
 305 
 306 static void gb_pwm_remove(struct gbphy_device *gbphy_dev)
 307 {
 308         struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev);
 309         struct gb_connection *connection = pwmc->connection;
 310         int ret;
 311 
 312         ret = gbphy_runtime_get_sync(gbphy_dev);
 313         if (ret)
 314                 gbphy_runtime_get_noresume(gbphy_dev);
 315 
 316         pwmchip_remove(&pwmc->chip);
 317         gb_connection_disable(connection);
 318         gb_connection_destroy(connection);
 319         kfree(pwmc);
 320 }
 321 
 322 static const struct gbphy_device_id gb_pwm_id_table[] = {
 323         { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
 324         { },
 325 };
 326 MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table);
 327 
 328 static struct gbphy_driver pwm_driver = {
 329         .name           = "pwm",
 330         .probe          = gb_pwm_probe,
 331         .remove         = gb_pwm_remove,
 332         .id_table       = gb_pwm_id_table,
 333 };
 334 
 335 module_gbphy_driver(pwm_driver);
 336 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */