Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Clemens Gruber | 1124 | 37.77% | 8 | 27.59% |
Steffen Trumtrar | 789 | 26.51% | 1 | 3.45% |
Mika Westerberg | 499 | 16.77% | 1 | 3.45% |
Sven Van Asbroeck | 303 | 10.18% | 3 | 10.34% |
Uwe Kleine-König | 141 | 4.74% | 7 | 24.14% |
David Jander | 60 | 2.02% | 3 | 10.34% |
Andy Shevchenko | 52 | 1.75% | 1 | 3.45% |
Rishi Gupta | 3 | 0.10% | 2 | 6.90% |
Lionel Vitte | 2 | 0.07% | 1 | 3.45% |
Thomas Gleixner | 2 | 0.07% | 1 | 3.45% |
Krzysztof Kozlowski | 1 | 0.03% | 1 | 3.45% |
Total | 2976 | 29 |
// SPDX-License-Identifier: GPL-2.0-only /* * Driver for PCA9685 16-channel 12-bit PWM LED controller * * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de> * Copyright (C) 2015 Clemens Gruber <clemens.gruber@pqgruber.com> * * based on the pwm-twl-led.c driver */ #include <linux/acpi.h> #include <linux/gpio/driver.h> #include <linux/i2c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/platform_device.h> #include <linux/property.h> #include <linux/pwm.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/delay.h> #include <linux/pm_runtime.h> #include <linux/bitmap.h> /* * Because the PCA9685 has only one prescaler per chip, only the first channel * that is enabled is allowed to change the prescale register. * PWM channels requested afterwards must use a period that results in the same * prescale setting as the one set by the first requested channel. * GPIOs do not count as enabled PWMs as they are not using the prescaler. */ #define PCA9685_MODE1 0x00 #define PCA9685_MODE2 0x01 #define PCA9685_SUBADDR1 0x02 #define PCA9685_SUBADDR2 0x03 #define PCA9685_SUBADDR3 0x04 #define PCA9685_ALLCALLADDR 0x05 #define PCA9685_LEDX_ON_L 0x06 #define PCA9685_LEDX_ON_H 0x07 #define PCA9685_LEDX_OFF_L 0x08 #define PCA9685_LEDX_OFF_H 0x09 #define PCA9685_ALL_LED_ON_L 0xFA #define PCA9685_ALL_LED_ON_H 0xFB #define PCA9685_ALL_LED_OFF_L 0xFC #define PCA9685_ALL_LED_OFF_H 0xFD #define PCA9685_PRESCALE 0xFE #define PCA9685_PRESCALE_MIN 0x03 /* => max. frequency of 1526 Hz */ #define PCA9685_PRESCALE_MAX 0xFF /* => min. frequency of 24 Hz */ #define PCA9685_COUNTER_RANGE 4096 #define PCA9685_OSC_CLOCK_MHZ 25 /* Internal oscillator with 25 MHz */ #define PCA9685_NUMREGS 0xFF #define PCA9685_MAXCHAN 0x10 #define LED_FULL BIT(4) #define MODE1_ALLCALL BIT(0) #define MODE1_SUB3 BIT(1) #define MODE1_SUB2 BIT(2) #define MODE1_SUB1 BIT(3) #define MODE1_SLEEP BIT(4) #define MODE2_INVRT BIT(4) #define MODE2_OUTDRV BIT(2) #define LED_N_ON_H(N) (PCA9685_LEDX_ON_H + (4 * (N))) #define LED_N_ON_L(N) (PCA9685_LEDX_ON_L + (4 * (N))) #define LED_N_OFF_H(N) (PCA9685_LEDX_OFF_H + (4 * (N))) #define LED_N_OFF_L(N) (PCA9685_LEDX_OFF_L + (4 * (N))) #define REG_ON_H(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_ON_H : LED_N_ON_H((C))) #define REG_ON_L(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_ON_L : LED_N_ON_L((C))) #define REG_OFF_H(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_OFF_H : LED_N_OFF_H((C))) #define REG_OFF_L(C) ((C) >= PCA9685_MAXCHAN ? PCA9685_ALL_LED_OFF_L : LED_N_OFF_L((C))) struct pca9685 { struct regmap *regmap; struct mutex lock; DECLARE_BITMAP(pwms_enabled, PCA9685_MAXCHAN + 1); #if IS_ENABLED(CONFIG_GPIOLIB) struct gpio_chip gpio; DECLARE_BITMAP(pwms_inuse, PCA9685_MAXCHAN + 1); #endif }; static inline struct pca9685 *to_pca(struct pwm_chip *chip) { return pwmchip_get_drvdata(chip); } /* This function is supposed to be called with the lock mutex held */ static bool pca9685_prescaler_can_change(struct pca9685 *pca, int channel) { /* No PWM enabled: Change allowed */ if (bitmap_empty(pca->pwms_enabled, PCA9685_MAXCHAN + 1)) return true; /* More than one PWM enabled: Change not allowed */ if (bitmap_weight(pca->pwms_enabled, PCA9685_MAXCHAN + 1) > 1) return false; /* * Only one PWM enabled: Change allowed if the PWM about to * be changed is the one that is already enabled */ return test_bit(channel, pca->pwms_enabled); } static int pca9685_read_reg(struct pwm_chip *chip, unsigned int reg, unsigned int *val) { struct pca9685 *pca = to_pca(chip); struct device *dev = pwmchip_parent(chip); int err; err = regmap_read(pca->regmap, reg, val); if (err) dev_err(dev, "regmap_read of register 0x%x failed: %pe\n", reg, ERR_PTR(err)); return err; } static int pca9685_write_reg(struct pwm_chip *chip, unsigned int reg, unsigned int val) { struct pca9685 *pca = to_pca(chip); struct device *dev = pwmchip_parent(chip); int err; err = regmap_write(pca->regmap, reg, val); if (err) dev_err(dev, "regmap_write to register 0x%x failed: %pe\n", reg, ERR_PTR(err)); return err; } /* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 -> 50%) */ static void pca9685_pwm_set_duty(struct pwm_chip *chip, int channel, unsigned int duty) { struct pwm_device *pwm = &chip->pwms[channel]; unsigned int on, off; if (duty == 0) { /* Set the full OFF bit, which has the highest precedence */ pca9685_write_reg(chip, REG_OFF_H(channel), LED_FULL); return; } else if (duty >= PCA9685_COUNTER_RANGE) { /* Set the full ON bit and clear the full OFF bit */ pca9685_write_reg(chip, REG_ON_H(channel), LED_FULL); pca9685_write_reg(chip, REG_OFF_H(channel), 0); return; } if (pwm->state.usage_power && channel < PCA9685_MAXCHAN) { /* * If usage_power is set, the pca9685 driver will phase shift * the individual channels relative to their channel number. * This improves EMI because the enabled channels no longer * turn on at the same time, while still maintaining the * configured duty cycle / power output. */ on = channel * PCA9685_COUNTER_RANGE / PCA9685_MAXCHAN; } else on = 0; off = (on + duty) % PCA9685_COUNTER_RANGE; /* Set ON time (clears full ON bit) */ pca9685_write_reg(chip, REG_ON_L(channel), on & 0xff); pca9685_write_reg(chip, REG_ON_H(channel), (on >> 8) & 0xf); /* Set OFF time (clears full OFF bit) */ pca9685_write_reg(chip, REG_OFF_L(channel), off & 0xff); pca9685_write_reg(chip, REG_OFF_H(channel), (off >> 8) & 0xf); } static unsigned int pca9685_pwm_get_duty(struct pwm_chip *chip, int channel) { struct pwm_device *pwm = &chip->pwms[channel]; unsigned int off = 0, on = 0, val = 0; if (WARN_ON(channel >= PCA9685_MAXCHAN)) { /* HW does not support reading state of "all LEDs" channel */ return 0; } pca9685_read_reg(chip, LED_N_OFF_H(channel), &off); if (off & LED_FULL) { /* Full OFF bit is set */ return 0; } pca9685_read_reg(chip, LED_N_ON_H(channel), &on); if (on & LED_FULL) { /* Full ON bit is set */ return PCA9685_COUNTER_RANGE; } pca9685_read_reg(chip, LED_N_OFF_L(channel), &val); off = ((off & 0xf) << 8) | (val & 0xff); if (!pwm->state.usage_power) return off; /* Read ON register to calculate duty cycle of staggered output */ if (pca9685_read_reg(chip, LED_N_ON_L(channel), &val)) { /* Reset val to 0 in case reading LED_N_ON_L failed */ val = 0; } on = ((on & 0xf) << 8) | (val & 0xff); return (off - on) & (PCA9685_COUNTER_RANGE - 1); } #if IS_ENABLED(CONFIG_GPIOLIB) static bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca, int pwm_idx) { bool is_inuse; mutex_lock(&pca->lock); if (pwm_idx >= PCA9685_MAXCHAN) { /* * "All LEDs" channel: * pretend already in use if any of the PWMs are requested */ if (!bitmap_empty(pca->pwms_inuse, PCA9685_MAXCHAN)) { is_inuse = true; goto out; } } else { /* * Regular channel: * pretend already in use if the "all LEDs" channel is requested */ if (test_bit(PCA9685_MAXCHAN, pca->pwms_inuse)) { is_inuse = true; goto out; } } is_inuse = test_and_set_bit(pwm_idx, pca->pwms_inuse); out: mutex_unlock(&pca->lock); return is_inuse; } static void pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) { mutex_lock(&pca->lock); clear_bit(pwm_idx, pca->pwms_inuse); mutex_unlock(&pca->lock); } static int pca9685_pwm_gpio_request(struct gpio_chip *gpio, unsigned int offset) { struct pwm_chip *chip = gpiochip_get_data(gpio); struct pca9685 *pca = to_pca(chip); if (pca9685_pwm_test_and_set_inuse(pca, offset)) return -EBUSY; pm_runtime_get_sync(pwmchip_parent(chip)); return 0; } static int pca9685_pwm_gpio_get(struct gpio_chip *gpio, unsigned int offset) { struct pwm_chip *chip = gpiochip_get_data(gpio); return pca9685_pwm_get_duty(chip, offset) != 0; } static void pca9685_pwm_gpio_set(struct gpio_chip *gpio, unsigned int offset, int value) { struct pwm_chip *chip = gpiochip_get_data(gpio); pca9685_pwm_set_duty(chip, offset, value ? PCA9685_COUNTER_RANGE : 0); } static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset) { struct pwm_chip *chip = gpiochip_get_data(gpio); struct pca9685 *pca = to_pca(chip); pca9685_pwm_set_duty(chip, offset, 0); pm_runtime_put(pwmchip_parent(chip)); pca9685_pwm_clear_inuse(pca, offset); } static int pca9685_pwm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { /* Always out */ return GPIO_LINE_DIRECTION_OUT; } static int pca9685_pwm_gpio_direction_input(struct gpio_chip *gpio, unsigned int offset) { return -EINVAL; } static int pca9685_pwm_gpio_direction_output(struct gpio_chip *gpio, unsigned int offset, int value) { pca9685_pwm_gpio_set(gpio, offset, value); return 0; } /* * The PCA9685 has a bit for turning the PWM output full off or on. Some * boards like Intel Galileo actually uses these as normal GPIOs so we * expose a GPIO chip here which can exclusively take over the underlying * PWM channel. */ static int pca9685_pwm_gpio_probe(struct pwm_chip *chip) { struct pca9685 *pca = to_pca(chip); struct device *dev = pwmchip_parent(chip); pca->gpio.label = dev_name(dev); pca->gpio.parent = dev; pca->gpio.request = pca9685_pwm_gpio_request; pca->gpio.free = pca9685_pwm_gpio_free; pca->gpio.get_direction = pca9685_pwm_gpio_get_direction; pca->gpio.direction_input = pca9685_pwm_gpio_direction_input; pca->gpio.direction_output = pca9685_pwm_gpio_direction_output; pca->gpio.get = pca9685_pwm_gpio_get; pca->gpio.set = pca9685_pwm_gpio_set; pca->gpio.base = -1; pca->gpio.ngpio = PCA9685_MAXCHAN; pca->gpio.can_sleep = true; return devm_gpiochip_add_data(dev, &pca->gpio, chip); } #else static inline bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca, int pwm_idx) { return false; } static inline void pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) { } static inline int pca9685_pwm_gpio_probe(struct pwm_chip *chip) { return 0; } #endif static void pca9685_set_sleep_mode(struct pwm_chip *chip, bool enable) { struct device *dev = pwmchip_parent(chip); struct pca9685 *pca = to_pca(chip); int err = regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP, enable ? MODE1_SLEEP : 0); if (err) { dev_err(dev, "regmap_update_bits of register 0x%x failed: %pe\n", PCA9685_MODE1, ERR_PTR(err)); return; } if (!enable) { /* Wait 500us for the oscillator to be back up */ udelay(500); } } static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { struct pca9685 *pca = to_pca(chip); unsigned long long duty, prescale; unsigned int val = 0; if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL; prescale = DIV_ROUND_CLOSEST_ULL(PCA9685_OSC_CLOCK_MHZ * state->period, PCA9685_COUNTER_RANGE * 1000) - 1; if (prescale < PCA9685_PRESCALE_MIN || prescale > PCA9685_PRESCALE_MAX) { dev_err(pwmchip_parent(chip), "pwm not changed: period out of bounds!\n"); return -EINVAL; } if (!state->enabled) { pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); return 0; } pca9685_read_reg(chip, PCA9685_PRESCALE, &val); if (prescale != val) { if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) { dev_err(pwmchip_parent(chip), "pwm not changed: periods of enabled pwms must match!\n"); return -EBUSY; } /* * Putting the chip briefly into SLEEP mode * at this point won't interfere with the * pm_runtime framework, because the pm_runtime * state is guaranteed active here. */ /* Put chip into sleep mode */ pca9685_set_sleep_mode(chip, true); /* Change the chip-wide output frequency */ pca9685_write_reg(chip, PCA9685_PRESCALE, prescale); /* Wake the chip up */ pca9685_set_sleep_mode(chip, false); } duty = PCA9685_COUNTER_RANGE * state->duty_cycle; duty = DIV_ROUND_UP_ULL(duty, state->period); pca9685_pwm_set_duty(chip, pwm->hwpwm, duty); return 0; } static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { struct pca9685 *pca = to_pca(chip); int ret; mutex_lock(&pca->lock); ret = __pca9685_pwm_apply(chip, pwm, state); if (ret == 0) { if (state->enabled) set_bit(pwm->hwpwm, pca->pwms_enabled); else clear_bit(pwm->hwpwm, pca->pwms_enabled); } mutex_unlock(&pca->lock); return ret; } static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { unsigned long long duty; unsigned int val = 0; /* Calculate (chip-wide) period from prescale value */ pca9685_read_reg(chip, PCA9685_PRESCALE, &val); /* * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000. * The following calculation is therefore only a multiplication * and we are not losing precision. */ state->period = (PCA9685_COUNTER_RANGE * 1000 / PCA9685_OSC_CLOCK_MHZ) * (val + 1); /* The (per-channel) polarity is fixed */ state->polarity = PWM_POLARITY_NORMAL; if (pwm->hwpwm >= PCA9685_MAXCHAN) { /* * The "all LEDs" channel does not support HW readout * Return 0 and disabled for backwards compatibility */ state->duty_cycle = 0; state->enabled = false; return 0; } state->enabled = true; duty = pca9685_pwm_get_duty(chip, pwm->hwpwm); state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE); return 0; } static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) { struct pca9685 *pca = to_pca(chip); if (pca9685_pwm_test_and_set_inuse(pca, pwm->hwpwm)) return -EBUSY; if (pwm->hwpwm < PCA9685_MAXCHAN) { /* PWMs - except the "all LEDs" channel - default to enabled */ mutex_lock(&pca->lock); set_bit(pwm->hwpwm, pca->pwms_enabled); mutex_unlock(&pca->lock); } pm_runtime_get_sync(pwmchip_parent(chip)); return 0; } static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { struct pca9685 *pca = to_pca(chip); mutex_lock(&pca->lock); pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); clear_bit(pwm->hwpwm, pca->pwms_enabled); mutex_unlock(&pca->lock); pm_runtime_put(pwmchip_parent(chip)); pca9685_pwm_clear_inuse(pca, pwm->hwpwm); } static const struct pwm_ops pca9685_pwm_ops = { .apply = pca9685_pwm_apply, .get_state = pca9685_pwm_get_state, .request = pca9685_pwm_request, .free = pca9685_pwm_free, }; static const struct regmap_config pca9685_regmap_i2c_config = { .reg_bits = 8, .val_bits = 8, .max_register = PCA9685_NUMREGS, .cache_type = REGCACHE_NONE, }; static int pca9685_pwm_probe(struct i2c_client *client) { struct pwm_chip *chip; struct pca9685 *pca; unsigned int reg; int ret; /* Add an extra channel for ALL_LED */ chip = devm_pwmchip_alloc(&client->dev, PCA9685_MAXCHAN + 1, sizeof(*pca)); if (IS_ERR(chip)) return PTR_ERR(chip); pca = to_pca(chip); pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config); if (IS_ERR(pca->regmap)) { ret = PTR_ERR(pca->regmap); dev_err(&client->dev, "Failed to initialize register map: %d\n", ret); return ret; } i2c_set_clientdata(client, chip); mutex_init(&pca->lock); ret = pca9685_read_reg(chip, PCA9685_MODE2, ®); if (ret) return ret; if (device_property_read_bool(&client->dev, "invert")) reg |= MODE2_INVRT; else reg &= ~MODE2_INVRT; if (device_property_read_bool(&client->dev, "open-drain")) reg &= ~MODE2_OUTDRV; else reg |= MODE2_OUTDRV; ret = pca9685_write_reg(chip, PCA9685_MODE2, reg); if (ret) return ret; /* Disable all LED ALLCALL and SUBx addresses to avoid bus collisions */ pca9685_read_reg(chip, PCA9685_MODE1, ®); reg &= ~(MODE1_ALLCALL | MODE1_SUB1 | MODE1_SUB2 | MODE1_SUB3); pca9685_write_reg(chip, PCA9685_MODE1, reg); /* Reset OFF/ON registers to POR default */ pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_L, 0); pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_H, LED_FULL); pca9685_write_reg(chip, PCA9685_ALL_LED_ON_L, 0); pca9685_write_reg(chip, PCA9685_ALL_LED_ON_H, LED_FULL); chip->ops = &pca9685_pwm_ops; ret = pwmchip_add(chip); if (ret < 0) return ret; ret = pca9685_pwm_gpio_probe(chip); if (ret < 0) { pwmchip_remove(chip); return ret; } pm_runtime_enable(&client->dev); if (pm_runtime_enabled(&client->dev)) { /* * Although the chip comes out of power-up in the sleep state, * we force it to sleep in case it was woken up before */ pca9685_set_sleep_mode(chip, true); pm_runtime_set_suspended(&client->dev); } else { /* Wake the chip up if runtime PM is disabled */ pca9685_set_sleep_mode(chip, false); } return 0; } static void pca9685_pwm_remove(struct i2c_client *client) { struct pwm_chip *chip = i2c_get_clientdata(client); pwmchip_remove(chip); if (!pm_runtime_enabled(&client->dev)) { /* Put chip in sleep state if runtime PM is disabled */ pca9685_set_sleep_mode(chip, true); } pm_runtime_disable(&client->dev); } static int __maybe_unused pca9685_pwm_runtime_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pwm_chip *chip = i2c_get_clientdata(client); pca9685_set_sleep_mode(chip, true); return 0; } static int __maybe_unused pca9685_pwm_runtime_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct pwm_chip *chip = i2c_get_clientdata(client); pca9685_set_sleep_mode(chip, false); return 0; } static const struct i2c_device_id pca9685_id[] = { { "pca9685" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, pca9685_id); #ifdef CONFIG_ACPI static const struct acpi_device_id pca9685_acpi_ids[] = { { "INT3492", 0 }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(acpi, pca9685_acpi_ids); #endif #ifdef CONFIG_OF static const struct of_device_id pca9685_dt_ids[] = { { .compatible = "nxp,pca9685-pwm", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, pca9685_dt_ids); #endif static const struct dev_pm_ops pca9685_pwm_pm = { SET_RUNTIME_PM_OPS(pca9685_pwm_runtime_suspend, pca9685_pwm_runtime_resume, NULL) }; static struct i2c_driver pca9685_i2c_driver = { .driver = { .name = "pca9685-pwm", .acpi_match_table = ACPI_PTR(pca9685_acpi_ids), .of_match_table = of_match_ptr(pca9685_dt_ids), .pm = &pca9685_pwm_pm, }, .probe = pca9685_pwm_probe, .remove = pca9685_pwm_remove, .id_table = pca9685_id, }; module_i2c_driver(pca9685_i2c_driver); MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de>"); MODULE_DESCRIPTION("PWM driver for PCA9685"); MODULE_LICENSE("GPL");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1