linux/drivers/pwm/pwm-pca9685.c
<<
>>
Prefs
   1/*
   2 * Driver for PCA9685 16-channel 12-bit PWM LED controller
   3 *
   4 * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
   5 *
   6 * based on the pwm-twl-led.c driver
   7 *
   8 * This program is free software; you can redistribute it and/or modify it
   9 * under the terms of the GNU General Public License version 2 as published by
  10 * the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful, but WITHOUT
  13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15 * more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along with
  18 * this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include <linux/i2c.h>
  22#include <linux/module.h>
  23#include <linux/platform_device.h>
  24#include <linux/pwm.h>
  25#include <linux/regmap.h>
  26#include <linux/slab.h>
  27
  28#define PCA9685_MODE1           0x00
  29#define PCA9685_MODE2           0x01
  30#define PCA9685_SUBADDR1        0x02
  31#define PCA9685_SUBADDR2        0x03
  32#define PCA9685_SUBADDR3        0x04
  33#define PCA9685_ALLCALLADDR     0x05
  34#define PCA9685_LEDX_ON_L       0x06
  35#define PCA9685_LEDX_ON_H       0x07
  36#define PCA9685_LEDX_OFF_L      0x08
  37#define PCA9685_LEDX_OFF_H      0x09
  38
  39#define PCA9685_ALL_LED_ON_L    0xFA
  40#define PCA9685_ALL_LED_ON_H    0xFB
  41#define PCA9685_ALL_LED_OFF_L   0xFC
  42#define PCA9685_ALL_LED_OFF_H   0xFD
  43#define PCA9685_PRESCALE        0xFE
  44
  45#define PCA9685_NUMREGS         0xFF
  46#define PCA9685_MAXCHAN         0x10
  47
  48#define LED_FULL                (1 << 4)
  49#define MODE1_SLEEP             (1 << 4)
  50#define MODE2_INVRT             (1 << 4)
  51#define MODE2_OUTDRV            (1 << 2)
  52
  53#define LED_N_ON_H(N)   (PCA9685_LEDX_ON_H + (4 * (N)))
  54#define LED_N_ON_L(N)   (PCA9685_LEDX_ON_L + (4 * (N)))
  55#define LED_N_OFF_H(N)  (PCA9685_LEDX_OFF_H + (4 * (N)))
  56#define LED_N_OFF_L(N)  (PCA9685_LEDX_OFF_L + (4 * (N)))
  57
  58struct pca9685 {
  59        struct pwm_chip chip;
  60        struct regmap *regmap;
  61        int active_cnt;
  62};
  63
  64static inline struct pca9685 *to_pca(struct pwm_chip *chip)
  65{
  66        return container_of(chip, struct pca9685, chip);
  67}
  68
  69static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  70                              int duty_ns, int period_ns)
  71{
  72        struct pca9685 *pca = to_pca(chip);
  73        unsigned long long duty;
  74        unsigned int reg;
  75
  76        if (duty_ns < 1) {
  77                if (pwm->hwpwm >= PCA9685_MAXCHAN)
  78                        reg = PCA9685_ALL_LED_OFF_H;
  79                else
  80                        reg = LED_N_OFF_H(pwm->hwpwm);
  81
  82                regmap_write(pca->regmap, reg, LED_FULL);
  83
  84                return 0;
  85        }
  86
  87        if (duty_ns == period_ns) {
  88                if (pwm->hwpwm >= PCA9685_MAXCHAN)
  89                        reg = PCA9685_ALL_LED_ON_H;
  90                else
  91                        reg = LED_N_ON_H(pwm->hwpwm);
  92
  93                regmap_write(pca->regmap, reg, LED_FULL);
  94
  95                return 0;
  96        }
  97
  98        duty = 4096 * (unsigned long long)duty_ns;
  99        duty = DIV_ROUND_UP_ULL(duty, period_ns);
 100
 101        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 102                reg = PCA9685_ALL_LED_OFF_L;
 103        else
 104                reg = LED_N_OFF_L(pwm->hwpwm);
 105
 106        regmap_write(pca->regmap, reg, (int)duty & 0xff);
 107
 108        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 109                reg = PCA9685_ALL_LED_OFF_H;
 110        else
 111                reg = LED_N_OFF_H(pwm->hwpwm);
 112
 113        regmap_write(pca->regmap, reg, ((int)duty >> 8) & 0xf);
 114
 115        return 0;
 116}
 117
 118static int pca9685_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 119{
 120        struct pca9685 *pca = to_pca(chip);
 121        unsigned int reg;
 122
 123        /*
 124         * The PWM subsystem does not support a pre-delay.
 125         * So, set the ON-timeout to 0
 126         */
 127        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 128                reg = PCA9685_ALL_LED_ON_L;
 129        else
 130                reg = LED_N_ON_L(pwm->hwpwm);
 131
 132        regmap_write(pca->regmap, reg, 0);
 133
 134        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 135                reg = PCA9685_ALL_LED_ON_H;
 136        else
 137                reg = LED_N_ON_H(pwm->hwpwm);
 138
 139        regmap_write(pca->regmap, reg, 0);
 140
 141        /*
 142         * Clear the full-off bit.
 143         * It has precedence over the others and must be off.
 144         */
 145        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 146                reg = PCA9685_ALL_LED_OFF_H;
 147        else
 148                reg = LED_N_OFF_H(pwm->hwpwm);
 149
 150        regmap_update_bits(pca->regmap, reg, LED_FULL, 0x0);
 151
 152        return 0;
 153}
 154
 155static void pca9685_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 156{
 157        struct pca9685 *pca = to_pca(chip);
 158        unsigned int reg;
 159
 160        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 161                reg = PCA9685_ALL_LED_OFF_H;
 162        else
 163                reg = LED_N_OFF_H(pwm->hwpwm);
 164
 165        regmap_write(pca->regmap, reg, LED_FULL);
 166
 167        /* Clear the LED_OFF counter. */
 168        if (pwm->hwpwm >= PCA9685_MAXCHAN)
 169                reg = PCA9685_ALL_LED_OFF_L;
 170        else
 171                reg = LED_N_OFF_L(pwm->hwpwm);
 172
 173        regmap_write(pca->regmap, reg, 0x0);
 174}
 175
 176static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 177{
 178        struct pca9685 *pca = to_pca(chip);
 179
 180        if (pca->active_cnt++ == 0)
 181                return regmap_update_bits(pca->regmap, PCA9685_MODE1,
 182                                          MODE1_SLEEP, 0x0);
 183
 184        return 0;
 185}
 186
 187static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 188{
 189        struct pca9685 *pca = to_pca(chip);
 190
 191        if (--pca->active_cnt == 0)
 192                regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
 193                                   MODE1_SLEEP);
 194}
 195
 196static const struct pwm_ops pca9685_pwm_ops = {
 197        .enable = pca9685_pwm_enable,
 198        .disable = pca9685_pwm_disable,
 199        .config = pca9685_pwm_config,
 200        .request = pca9685_pwm_request,
 201        .free = pca9685_pwm_free,
 202        .owner = THIS_MODULE,
 203};
 204
 205static struct regmap_config pca9685_regmap_i2c_config = {
 206        .reg_bits = 8,
 207        .val_bits = 8,
 208        .max_register = PCA9685_NUMREGS,
 209        .cache_type = REGCACHE_NONE,
 210};
 211
 212static int pca9685_pwm_probe(struct i2c_client *client,
 213                                const struct i2c_device_id *id)
 214{
 215        struct device_node *np = client->dev.of_node;
 216        struct pca9685 *pca;
 217        int ret;
 218        int mode2;
 219
 220        pca = devm_kzalloc(&client->dev, sizeof(*pca), GFP_KERNEL);
 221        if (!pca)
 222                return -ENOMEM;
 223
 224        pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config);
 225        if (IS_ERR(pca->regmap)) {
 226                ret = PTR_ERR(pca->regmap);
 227                dev_err(&client->dev, "Failed to initialize register map: %d\n",
 228                        ret);
 229                return ret;
 230        }
 231
 232        i2c_set_clientdata(client, pca);
 233
 234        regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
 235
 236        if (of_property_read_bool(np, "invert"))
 237                mode2 |= MODE2_INVRT;
 238        else
 239                mode2 &= ~MODE2_INVRT;
 240
 241        if (of_property_read_bool(np, "open-drain"))
 242                mode2 &= ~MODE2_OUTDRV;
 243        else
 244                mode2 |= MODE2_OUTDRV;
 245
 246        regmap_write(pca->regmap, PCA9685_MODE2, mode2);
 247
 248        /* clear all "full off" bits */
 249        regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, 0);
 250        regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, 0);
 251
 252        pca->chip.ops = &pca9685_pwm_ops;
 253        /* add an extra channel for ALL_LED */
 254        pca->chip.npwm = PCA9685_MAXCHAN + 1;
 255
 256        pca->chip.dev = &client->dev;
 257        pca->chip.base = -1;
 258        pca->chip.can_sleep = true;
 259
 260        return pwmchip_add(&pca->chip);
 261}
 262
 263static int pca9685_pwm_remove(struct i2c_client *client)
 264{
 265        struct pca9685 *pca = i2c_get_clientdata(client);
 266
 267        regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
 268                           MODE1_SLEEP);
 269
 270        return pwmchip_remove(&pca->chip);
 271}
 272
 273static const struct i2c_device_id pca9685_id[] = {
 274        { "pca9685", 0 },
 275        { /* sentinel */ },
 276};
 277MODULE_DEVICE_TABLE(i2c, pca9685_id);
 278
 279static const struct of_device_id pca9685_dt_ids[] = {
 280        { .compatible = "nxp,pca9685-pwm", },
 281        { /* sentinel */ }
 282};
 283MODULE_DEVICE_TABLE(of, pca9685_dt_ids);
 284
 285static struct i2c_driver pca9685_i2c_driver = {
 286        .driver = {
 287                .name = "pca9685-pwm",
 288                .owner = THIS_MODULE,
 289                .of_match_table = pca9685_dt_ids,
 290        },
 291        .probe = pca9685_pwm_probe,
 292        .remove = pca9685_pwm_remove,
 293        .id_table = pca9685_id,
 294};
 295
 296module_i2c_driver(pca9685_i2c_driver);
 297
 298MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de>");
 299MODULE_DESCRIPTION("PWM driver for PCA9685");
 300MODULE_LICENSE("GPL");
 301
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.