Lines Matching +full:pwm +full:- +full:off +full:- +full:delay +full:- +full:ms
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
9 * Based on leds-pca955x.c
11 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
12 * LED driver for the PCA9634/5 I2C LED driver (7-bit slave address set by hw.)
22 * or by adding the 'nxp,hw-blink' property to the DTS.
26 #include <linux/delay.h>
37 #define PCA963X_LED_OFF 0x0 /* LED driver off */
39 #define PCA963X_LED_PWM 0x2 /* Controlled through PWM */
40 #define PCA963X_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
42 #define PCA963X_MODE2_OUTDRV 0x04 /* Open-drain or totem pole */
120 struct i2c_client *client = led->chip->client; in pca963x_brightness()
121 struct pca963x_chipdef *chipdef = led->chip->chipdef; in pca963x_brightness()
126 ledout_addr = chipdef->ledout_base + (led->led_num / 4); in pca963x_brightness()
127 shift = 2 * (led->led_num % 4); in pca963x_brightness()
133 if (led->blinking) { in pca963x_brightness()
137 led->led_num, in pca963x_brightness()
147 led->blinking = false; in pca963x_brightness()
152 led->led_num, in pca963x_brightness()
157 if (led->blinking) in pca963x_brightness()
171 struct i2c_client *client = led->chip->client; in pca963x_blink()
172 struct pca963x_chipdef *chipdef = led->chip->chipdef; in pca963x_blink()
176 ledout_addr = chipdef->ledout_base + (led->led_num / 4); in pca963x_blink()
177 shift = 2 * (led->led_num % 4); in pca963x_blink()
181 i2c_smbus_write_byte_data(client, chipdef->grppwm, led->gdc); in pca963x_blink()
183 i2c_smbus_write_byte_data(client, chipdef->grpfreq, led->gfrq); in pca963x_blink()
189 mutex_lock(&led->chip->mutex); in pca963x_blink()
197 mutex_unlock(&led->chip->mutex); in pca963x_blink()
198 led->blinking = true; in pca963x_blink()
203 struct i2c_client *client = led->chip->client; in pca963x_power_state()
204 unsigned long *leds_on = &led->chip->leds_on; in pca963x_power_state()
207 if (led->led_cdev.brightness) in pca963x_power_state()
208 set_bit(led->led_num, leds_on); in pca963x_power_state()
210 clear_bit(led->led_num, leds_on); in pca963x_power_state()
227 mutex_lock(&led->chip->mutex); in pca963x_led_set()
235 mutex_unlock(&led->chip->mutex); in pca963x_led_set()
242 unsigned int scaling = led->chip->chipdef->scaling; in pca963x_period_scale()
259 /* If both zero, pick reasonable defaults of 500ms each */ in pca963x_blink_set()
276 * From manual: duty cycle = (GDC / 256) -> in pca963x_blink_set()
277 * (time_on / period) = (GDC / 256) -> in pca963x_blink_set()
284 * So, period (in ms) = (((GFRQ + 1) / 24) * 1000) -> in pca963x_blink_set()
285 * GFRQ = ((period * 24 / 1000) - 1) in pca963x_blink_set()
287 gfrq = (period * 24 / 1000) - 1; in pca963x_blink_set()
289 led->gdc = gdc; in pca963x_blink_set()
290 led->gfrq = gfrq; in pca963x_blink_set()
293 led->led_cdev.brightness = LED_FULL; in pca963x_blink_set()
305 struct pca963x_chipdef *chipdef = chip->chipdef; in pca963x_register_leds()
306 struct pca963x_led *led = chip->leds; in pca963x_register_leds()
307 struct device *dev = &client->dev; in pca963x_register_leds()
314 if (device_property_read_u32(dev, "nxp,period-scale", in pca963x_register_leds()
315 &chipdef->scaling)) in pca963x_register_leds()
316 chipdef->scaling = 1000; in pca963x_register_leds()
318 hw_blink = device_property_read_bool(dev, "nxp,hw-blink"); in pca963x_register_leds()
324 /* default to open-drain unless totem pole (push-pull) is specified */ in pca963x_register_leds()
325 if (device_property_read_bool(dev, "nxp,totem-pole")) in pca963x_register_leds()
330 /* default to non-inverted output, unless inverted is specified */ in pca963x_register_leds()
331 if (device_property_read_bool(dev, "nxp,inverted-out")) in pca963x_register_leds()
345 if (ret || reg >= chipdef->n_leds) { in pca963x_register_leds()
348 ret = -EINVAL; in pca963x_register_leds()
352 led->led_num = reg; in pca963x_register_leds()
353 led->chip = chip; in pca963x_register_leds()
354 led->led_cdev.brightness_set_blocking = pca963x_led_set; in pca963x_register_leds()
356 led->led_cdev.blink_set = pca963x_blink_set; in pca963x_register_leds()
357 led->blinking = false; in pca963x_register_leds()
363 client->adapter->nr, client->addr, reg); in pca963x_register_leds()
366 ret = devm_led_classdev_register_ext(dev, &led->led_cdev, in pca963x_register_leds()
395 struct device *dev = &client->dev; in pca963x_probe()
400 chipdef = &pca963x_chipdefs[id->driver_data]; in pca963x_probe()
403 if (!count || count > chipdef->n_leds) { in pca963x_probe()
405 dev_fwnode(dev), chipdef->n_leds); in pca963x_probe()
406 return -EINVAL; in pca963x_probe()
411 return -ENOMEM; in pca963x_probe()
415 mutex_init(&chip->mutex); in pca963x_probe()
416 chip->chipdef = chipdef; in pca963x_probe()
417 chip->client = client; in pca963x_probe()
419 /* Turn off LEDs by default*/ in pca963x_probe()
420 for (i = 0; i < chipdef->n_leds / 4; i++) in pca963x_probe()
421 i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00); in pca963x_probe()
423 /* Disable LED all-call address, and power down initially */ in pca963x_probe()
431 .name = "leds-pca963x",
440 MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");