Lines Matching +full:pwm +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-only
3 * pca9532.c - 16-bit Led dimmer
18 #include <linux/leds-pca9532.h>
54 u8 pwm[2]; member
108 .name = "leds-pca953x",
116 /* We have two pwm/blinkers, but 16 possible leds to drive. Additionally,
117 * the clever Thecus people are using one pwm to drive the beeper. So,
118 * as a compromise we average one pwm to the values requested by all
121 static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, in pca9532_calcpwm() argument
126 for (i = 0; i < data->chip_info->num_leds; i++) { in pca9532_calcpwm()
127 if (data->leds[i].type == PCA9532_TYPE_LED && in pca9532_calcpwm()
128 data->leds[i].state == PCA9532_PWM0+pwm) { in pca9532_calcpwm()
130 b += data->leds[i].ldev.brightness; in pca9532_calcpwm()
134 dev_err(&client->dev, in pca9532_calcpwm()
137 return -EINVAL; in pca9532_calcpwm()
141 return -EINVAL; in pca9532_calcpwm()
142 data->pwm[pwm] = b; in pca9532_calcpwm()
143 data->psc[pwm] = blink; in pca9532_calcpwm()
147 static int pca9532_setpwm(struct i2c_client *client, int pwm) in pca9532_setpwm() argument
150 u8 maxleds = data->chip_info->num_leds; in pca9532_setpwm()
152 mutex_lock(&data->update_lock); in pca9532_setpwm()
153 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm), in pca9532_setpwm()
154 data->pwm[pwm]); in pca9532_setpwm()
155 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm), in pca9532_setpwm()
156 data->psc[pwm]); in pca9532_setpwm()
157 mutex_unlock(&data->update_lock); in pca9532_setpwm()
164 struct i2c_client *client = led->client; in pca9532_setled()
166 u8 maxleds = data->chip_info->num_leds; in pca9532_setled()
169 mutex_lock(&data->update_lock); in pca9532_setled()
170 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); in pca9532_setled()
172 reg = reg & ~LED_MASK(led->id); in pca9532_setled()
174 reg = reg | (led->state << LED_SHIFT(led->id)); in pca9532_setled()
175 i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg); in pca9532_setled()
176 mutex_unlock(&data->update_lock); in pca9532_setled()
186 led->state = PCA9532_OFF; in pca9532_set_brightness()
188 led->state = PCA9532_ON; in pca9532_set_brightness()
190 led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ in pca9532_set_brightness()
191 err = pca9532_calcpwm(led->client, PCA9532_PWM_ID_0, 0, value); in pca9532_set_brightness()
195 if (led->state == PCA9532_PWM0) in pca9532_set_brightness()
196 pca9532_setpwm(led->client, PCA9532_PWM_ID_0); in pca9532_set_brightness()
204 struct pca9532_data *data = i2c_get_clientdata(led->client); in pca9532_update_hw_blink()
209 for (i = 0; i < data->chip_info->num_leds; i++) { in pca9532_update_hw_blink()
210 struct pca9532_led *other = &data->leds[i]; in pca9532_update_hw_blink()
215 if (other->state == PCA9532_PWM1) { in pca9532_update_hw_blink()
216 if (other->ldev.blink_delay_on != delay_on || in pca9532_update_hw_blink()
217 other->ldev.blink_delay_off != delay_off) { in pca9532_update_hw_blink()
219 return -EINVAL; in pca9532_update_hw_blink()
224 psc = ((delay_on + delay_off) * PCA9532_PWM_PERIOD_DIV - 1) / 1000; in pca9532_update_hw_blink()
227 return -EINVAL; in pca9532_update_hw_blink()
230 led->state = PCA9532_PWM1; in pca9532_update_hw_blink()
231 data->psc[PCA9532_PWM_ID_1] = psc; in pca9532_update_hw_blink()
232 data->pwm[PCA9532_PWM_ID_1] = (delay_on * PCA9532_PWM_DUTY_DIV) / (delay_on + delay_off); in pca9532_update_hw_blink()
234 return pca9532_setpwm(data->client, PCA9532_PWM_ID_1); in pca9532_update_hw_blink()
241 struct i2c_client *client = led->client; in pca9532_set_blink()
245 if (!data->hw_blink) in pca9532_set_blink()
246 return -EINVAL; in pca9532_set_blink()
269 return -1; in pca9532_event()
271 /* XXX: allow different kind of beeps with psc/pwm modifications */ in pca9532_event()
273 data->pwm[PCA9532_PWM_ID_1] = 127; in pca9532_event()
275 data->pwm[PCA9532_PWM_ID_1] = 0; in pca9532_event()
277 schedule_work(&data->work); in pca9532_event()
286 u8 maxleds = data->chip_info->num_leds; in pca9532_input_work()
288 mutex_lock(&data->update_lock); in pca9532_input_work()
289 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1), in pca9532_input_work()
290 data->pwm[PCA9532_PWM_ID_1]); in pca9532_input_work()
291 mutex_unlock(&data->update_lock); in pca9532_input_work()
296 struct i2c_client *client = led->client; in pca9532_getled()
298 u8 maxleds = data->chip_info->num_leds; in pca9532_getled()
302 mutex_lock(&data->update_lock); in pca9532_getled()
303 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); in pca9532_getled()
304 ret = (reg & LED_MASK(led->id)) >> LED_SHIFT(led->id); in pca9532_getled()
305 mutex_unlock(&data->update_lock); in pca9532_getled()
310 static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset) in pca9532_gpio_request_pin() argument
313 struct pca9532_led *led = &data->leds[offset]; in pca9532_gpio_request_pin()
315 if (led->type == PCA9532_TYPE_GPIO) in pca9532_gpio_request_pin()
318 return -EBUSY; in pca9532_gpio_request_pin()
321 static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val) in pca9532_gpio_set_value() argument
324 struct pca9532_led *led = &data->leds[offset]; in pca9532_gpio_set_value()
327 led->state = PCA9532_ON; in pca9532_gpio_set_value()
329 led->state = PCA9532_OFF; in pca9532_gpio_set_value()
334 static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset) in pca9532_gpio_get_value() argument
339 reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset)); in pca9532_gpio_get_value()
341 return !!(reg & (1 << (offset % 8))); in pca9532_gpio_get_value()
344 static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset) in pca9532_gpio_direction_input() argument
347 pca9532_gpio_set_value(gc, offset, 0); in pca9532_gpio_direction_input()
352 static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val) in pca9532_gpio_direction_output() argument
354 pca9532_gpio_set_value(gc, offset, val); in pca9532_gpio_direction_output()
364 while (--i >= 0) { in pca9532_destroy_devices()
365 switch (data->leds[i].type) { in pca9532_destroy_devices()
370 led_classdev_unregister(&data->leds[i].ldev); in pca9532_destroy_devices()
373 if (data->idev != NULL) { in pca9532_destroy_devices()
374 cancel_work_sync(&data->work); in pca9532_destroy_devices()
375 data->idev = NULL; in pca9532_destroy_devices()
382 if (data->gpio.parent) in pca9532_destroy_devices()
383 gpiochip_remove(&data->gpio); in pca9532_destroy_devices()
392 u8 maxleds = data->chip_info->num_leds; in pca9532_configure()
395 data->pwm[i] = pdata->pwm[i]; in pca9532_configure()
396 data->psc[i] = pdata->psc[i]; in pca9532_configure()
398 data->pwm[i]); in pca9532_configure()
400 data->psc[i]); in pca9532_configure()
403 data->hw_blink = true; in pca9532_configure()
404 for (i = 0; i < data->chip_info->num_leds; i++) { in pca9532_configure()
405 struct pca9532_led *led = &data->leds[i]; in pca9532_configure()
406 struct pca9532_led *pled = &pdata->leds[i]; in pca9532_configure()
407 led->client = client; in pca9532_configure()
408 led->id = i; in pca9532_configure()
409 led->type = pled->type; in pca9532_configure()
410 switch (led->type) { in pca9532_configure()
417 if (pled->state == PCA9532_KEEP) in pca9532_configure()
418 led->state = pca9532_getled(led); in pca9532_configure()
420 led->state = pled->state; in pca9532_configure()
421 led->name = pled->name; in pca9532_configure()
422 led->ldev.name = led->name; in pca9532_configure()
423 led->ldev.default_trigger = pled->default_trigger; in pca9532_configure()
424 led->ldev.brightness = LED_OFF; in pca9532_configure()
425 led->ldev.brightness_set_blocking = in pca9532_configure()
427 led->ldev.blink_set = pca9532_set_blink; in pca9532_configure()
428 err = led_classdev_register(&client->dev, &led->ldev); in pca9532_configure()
430 dev_err(&client->dev, in pca9532_configure()
432 led->name); in pca9532_configure()
439 data->hw_blink = false; in pca9532_configure()
440 BUG_ON(data->idev); in pca9532_configure()
441 led->state = PCA9532_PWM1; in pca9532_configure()
443 data->idev = devm_input_allocate_device(&client->dev); in pca9532_configure()
444 if (data->idev == NULL) { in pca9532_configure()
445 err = -ENOMEM; in pca9532_configure()
448 data->idev->name = pled->name; in pca9532_configure()
449 data->idev->phys = "i2c/pca9532"; in pca9532_configure()
450 data->idev->id.bustype = BUS_HOST; in pca9532_configure()
451 data->idev->id.vendor = 0x001f; in pca9532_configure()
452 data->idev->id.product = 0x0001; in pca9532_configure()
453 data->idev->id.version = 0x0100; in pca9532_configure()
454 data->idev->evbit[0] = BIT_MASK(EV_SND); in pca9532_configure()
455 data->idev->sndbit[0] = BIT_MASK(SND_BELL) | in pca9532_configure()
457 data->idev->event = pca9532_event; in pca9532_configure()
458 input_set_drvdata(data->idev, data); in pca9532_configure()
459 INIT_WORK(&data->work, pca9532_input_work); in pca9532_configure()
460 err = input_register_device(data->idev); in pca9532_configure()
462 cancel_work_sync(&data->work); in pca9532_configure()
463 data->idev = NULL; in pca9532_configure()
472 data->gpio.label = "gpio-pca9532"; in pca9532_configure()
473 data->gpio.direction_input = pca9532_gpio_direction_input; in pca9532_configure()
474 data->gpio.direction_output = pca9532_gpio_direction_output; in pca9532_configure()
475 data->gpio.set = pca9532_gpio_set_value; in pca9532_configure()
476 data->gpio.get = pca9532_gpio_get_value; in pca9532_configure()
477 data->gpio.request = pca9532_gpio_request_pin; in pca9532_configure()
478 data->gpio.can_sleep = 1; in pca9532_configure()
479 data->gpio.base = pdata->gpio_base; in pca9532_configure()
480 data->gpio.ngpio = data->chip_info->num_leds; in pca9532_configure()
481 data->gpio.parent = &client->dev; in pca9532_configure()
482 data->gpio.owner = THIS_MODULE; in pca9532_configure()
484 err = gpiochip_add_data(&data->gpio, data); in pca9532_configure()
486 /* Use data->gpio.dev as a flag for freeing gpiochip */ in pca9532_configure()
487 data->gpio.parent = NULL; in pca9532_configure()
488 dev_warn(&client->dev, "could not add gpiochip\n"); in pca9532_configure()
490 dev_info(&client->dev, "gpios %i...%i\n", in pca9532_configure()
491 data->gpio.base, data->gpio.base + in pca9532_configure()
492 data->gpio.ngpio - 1); in pca9532_configure()
517 return ERR_PTR(-ENOMEM); in pca9532_of_populate_pdata()
519 pdata->gpio_base = -1; in pca9532_of_populate_pdata()
521 of_property_read_u8_array(np, "nxp,pwm", &pdata->pwm[PCA9532_PWM_ID_0], in pca9532_of_populate_pdata()
522 ARRAY_SIZE(pdata->pwm)); in pca9532_of_populate_pdata()
523 of_property_read_u8_array(np, "nxp,psc", &pdata->psc[PCA9532_PWM_ID_0], in pca9532_of_populate_pdata()
524 ARRAY_SIZE(pdata->psc)); in pca9532_of_populate_pdata()
528 &pdata->leds[i].name)) in pca9532_of_populate_pdata()
529 pdata->leds[i].name = child->name; in pca9532_of_populate_pdata()
530 of_property_read_u32(child, "type", &pdata->leds[i].type); in pca9532_of_populate_pdata()
531 of_property_read_string(child, "linux,default-trigger", in pca9532_of_populate_pdata()
532 &pdata->leds[i].default_trigger); in pca9532_of_populate_pdata()
533 if (!of_property_read_string(child, "default-state", &state)) { in pca9532_of_populate_pdata()
535 pdata->leds[i].state = PCA9532_ON; in pca9532_of_populate_pdata()
537 pdata->leds[i].state = PCA9532_KEEP; in pca9532_of_populate_pdata()
552 dev_get_platdata(&client->dev); in pca9532_probe()
553 struct device_node *np = dev_of_node(&client->dev); in pca9532_probe()
558 pca9532_of_populate_pdata(&client->dev, np); in pca9532_probe()
562 dev_err(&client->dev, "no platform data\n"); in pca9532_probe()
563 return -EINVAL; in pca9532_probe()
565 devid = (int)(uintptr_t)of_device_get_match_data(&client->dev); in pca9532_probe()
567 devid = id->driver_data; in pca9532_probe()
570 if (!i2c_check_functionality(client->adapter, in pca9532_probe()
572 return -EIO; in pca9532_probe()
574 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); in pca9532_probe()
576 return -ENOMEM; in pca9532_probe()
578 data->chip_info = &pca9532_chip_info_tbl[devid]; in pca9532_probe()
580 dev_info(&client->dev, "setting platform data\n"); in pca9532_probe()
582 data->client = client; in pca9532_probe()
583 mutex_init(&data->update_lock); in pca9532_probe()
592 pca9532_destroy_devices(data, data->chip_info->num_leds); in pca9532_remove()