linux/drivers/staging/greybus/pwm.c
<<
>>
Prefs
   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_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
 215static 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
 223static 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
 230static 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
 237static 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
 247static 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
 297exit_connection_disable:
 298        gb_connection_disable(connection);
 299exit_connection_destroy:
 300        gb_connection_destroy(connection);
 301exit_pwmc_free:
 302        kfree(pwmc);
 303        return ret;
 304}
 305
 306static 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
 322static const struct gbphy_device_id gb_pwm_id_table[] = {
 323        { GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
 324        { },
 325};
 326MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table);
 327
 328static 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
 335module_gbphy_driver(pwm_driver);
 336MODULE_LICENSE("GPL v2");
 337