Lines Matching +full:led +full:- +full:7

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.)
18 * in identical fashion. The delay_on/delay_off values of the last LED
22 * or by adding the 'nxp,hw-blink' property to the DTS.
36 /* LED select registers determine the source that drives LED outputs */
37 #define PCA963X_LED_OFF 0x0 /* LED driver off */
38 #define PCA963X_LED_ON 0x1 /* LED driver on */
42 #define PCA963X_MODE2_OUTDRV 0x04 /* Open-drain or totem pole */
116 static int pca963x_brightness(struct pca963x_led *led, in pca963x_brightness() argument
119 struct i2c_client *client = led->chip->client; in pca963x_brightness()
120 struct pca963x_chipdef *chipdef = led->chip->chipdef; in pca963x_brightness()
125 ledout_addr = chipdef->ledout_base + (led->led_num / 4); in pca963x_brightness()
126 shift = 2 * (led->led_num % 4); in pca963x_brightness()
142 led->led_num, in pca963x_brightness()
155 static void pca963x_blink(struct pca963x_led *led) in pca963x_blink() argument
157 struct i2c_client *client = led->chip->client; in pca963x_blink()
158 struct pca963x_chipdef *chipdef = led->chip->chipdef; in pca963x_blink()
162 ledout_addr = chipdef->ledout_base + (led->led_num / 4); in pca963x_blink()
163 shift = 2 * (led->led_num % 4); in pca963x_blink()
167 i2c_smbus_write_byte_data(client, chipdef->grppwm, led->gdc); in pca963x_blink()
169 i2c_smbus_write_byte_data(client, chipdef->grpfreq, led->gfrq); in pca963x_blink()
175 mutex_lock(&led->chip->mutex); in pca963x_blink()
183 mutex_unlock(&led->chip->mutex); in pca963x_blink()
186 static int pca963x_power_state(struct pca963x_led *led) in pca963x_power_state() argument
188 struct i2c_client *client = led->chip->client; in pca963x_power_state()
189 unsigned long *leds_on = &led->chip->leds_on; in pca963x_power_state()
192 if (led->led_cdev.brightness) in pca963x_power_state()
193 set_bit(led->led_num, leds_on); in pca963x_power_state()
195 clear_bit(led->led_num, leds_on); in pca963x_power_state()
207 struct pca963x_led *led; in pca963x_led_set() local
210 led = container_of(led_cdev, struct pca963x_led, led_cdev); in pca963x_led_set()
212 mutex_lock(&led->chip->mutex); in pca963x_led_set()
214 ret = pca963x_brightness(led, value); in pca963x_led_set()
217 ret = pca963x_power_state(led); in pca963x_led_set()
220 mutex_unlock(&led->chip->mutex); in pca963x_led_set()
224 static unsigned int pca963x_period_scale(struct pca963x_led *led, in pca963x_period_scale() argument
227 unsigned int scaling = led->chip->chipdef->scaling; in pca963x_period_scale()
236 struct pca963x_led *led; in pca963x_blink_set() local
239 led = container_of(led_cdev, struct pca963x_led, led_cdev); in pca963x_blink_set()
250 period = pca963x_period_scale(led, time_on + time_off); in pca963x_blink_set()
257 period = pca963x_period_scale(led, 1000); in pca963x_blink_set()
261 * From manual: duty cycle = (GDC / 256) -> in pca963x_blink_set()
262 * (time_on / period) = (GDC / 256) -> in pca963x_blink_set()
265 gdc = (pca963x_period_scale(led, time_on) * 256) / period; in pca963x_blink_set()
269 * So, period (in ms) = (((GFRQ + 1) / 24) * 1000) -> in pca963x_blink_set()
270 * GFRQ = ((period * 24 / 1000) - 1) in pca963x_blink_set()
272 gfrq = (period * 24 / 1000) - 1; in pca963x_blink_set()
274 led->gdc = gdc; in pca963x_blink_set()
275 led->gfrq = gfrq; in pca963x_blink_set()
277 pca963x_blink(led); in pca963x_blink_set()
288 struct pca963x_chipdef *chipdef = chip->chipdef; in pca963x_register_leds()
289 struct pca963x_led *led = chip->leds; in pca963x_register_leds() local
290 struct device *dev = &client->dev; in pca963x_register_leds()
297 if (device_property_read_u32(dev, "nxp,period-scale", in pca963x_register_leds()
298 &chipdef->scaling)) in pca963x_register_leds()
299 chipdef->scaling = 1000; in pca963x_register_leds()
301 hw_blink = device_property_read_bool(dev, "nxp,hw-blink"); in pca963x_register_leds()
307 /* default to open-drain unless totem pole (push-pull) is specified */ in pca963x_register_leds()
308 if (device_property_read_bool(dev, "nxp,totem-pole")) in pca963x_register_leds()
313 /* default to non-inverted output, unless inverted is specified */ in pca963x_register_leds()
314 if (device_property_read_bool(dev, "nxp,inverted-out")) in pca963x_register_leds()
328 if (ret || reg >= chipdef->n_leds) { in pca963x_register_leds()
331 ret = -EINVAL; in pca963x_register_leds()
335 led->led_num = reg; in pca963x_register_leds()
336 led->chip = chip; in pca963x_register_leds()
337 led->led_cdev.brightness_set_blocking = pca963x_led_set; in pca963x_register_leds()
339 led->led_cdev.blink_set = pca963x_blink_set; in pca963x_register_leds()
345 client->adapter->nr, client->addr, reg); in pca963x_register_leds()
348 ret = devm_led_classdev_register_ext(dev, &led->led_cdev, in pca963x_register_leds()
351 dev_err(dev, "Failed to register LED for node %pfw\n", in pca963x_register_leds()
356 ++led; in pca963x_register_leds()
377 struct device *dev = &client->dev; in pca963x_probe()
382 chipdef = &pca963x_chipdefs[id->driver_data]; in pca963x_probe()
385 if (!count || count > chipdef->n_leds) { in pca963x_probe()
387 dev_fwnode(dev), chipdef->n_leds); in pca963x_probe()
388 return -EINVAL; in pca963x_probe()
393 return -ENOMEM; in pca963x_probe()
397 mutex_init(&chip->mutex); in pca963x_probe()
398 chip->chipdef = chipdef; in pca963x_probe()
399 chip->client = client; in pca963x_probe()
402 for (i = 0; i < chipdef->n_leds / 4; i++) in pca963x_probe()
403 i2c_smbus_write_byte_data(client, chipdef->ledout_base + i, 0x00); in pca963x_probe()
405 /* Disable LED all-call address, and power down initially */ in pca963x_probe()
413 .name = "leds-pca963x",
422 MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
423 MODULE_DESCRIPTION("PCA963X LED driver");