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