Lines Matching +full:gpio +full:- +full:leds
2 * Copyright 2007-2008 Extreme Engineering Solutions, Inc.
4 * Author: Nate Case <ncase@xes-inc.com>
14 * Device Description 7-bit slave address
15 * ------ ----------- -------------------
16 * PCA9550 2-bit driver 0x60 .. 0x61
17 * PCA9551 8-bit driver 0x60 .. 0x67
18 * PCA9552 16-bit driver 0x60 .. 0x67
19 * PCA9553/01 4-bit driver 0x62
20 * PCA9553/02 4-bit driver 0x63
25 * ---------------- -----------
28 * NUM_INPUT_REGS - 1 Last Input register X
37 * + NUM_LED_REGS - 1 Last LED selector
47 #include <linux/gpio.h>
49 #include <linux/leds.h>
56 #include <dt-bindings/leds/leds-pca955x.h>
60 #define PCA955X_LS_LED_OFF 0x1 /* Output HI-Z */
77 u8 slv_addr; /* 7-bit slave address mask */
124 struct pca955x_led *leds; member
128 struct gpio_chip gpio; member
142 struct pca955x_led *leds; member
160 * the appropriate 2-bit state value set for the given LED number (0-3).
178 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n, in pca955x_write_psc()
181 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", in pca955x_write_psc()
191 * Duty cycle is (256 - PWMx) / 256
199 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n, in pca955x_write_pwm()
202 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", in pca955x_write_pwm()
217 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n, in pca955x_write_ls()
220 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", in pca955x_write_ls()
235 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n); in pca955x_read_ls()
237 dev_err(&client->dev, "%s: reg 0x%x, err %d\n", in pca955x_read_ls()
251 int chip_ls; /* which LSx to use (0-3 potentially) */ in pca955x_led_set()
252 int ls_led; /* which set of bits within LSx to use (0-3) */ in pca955x_led_set()
256 pca955x = pca955x_led->pca955x; in pca955x_led_set()
258 chip_ls = pca955x_led->led_num / 4; in pca955x_led_set()
259 ls_led = pca955x_led->led_num % 4; in pca955x_led_set()
261 mutex_lock(&pca955x->lock); in pca955x_led_set()
263 ret = pca955x_read_ls(pca955x->client, chip_ls, &ls); in pca955x_led_set()
280 * side effect of making all LEDs on the chip share the in pca955x_led_set()
285 ret = pca955x_write_pwm(pca955x->client, 1, 255 - value); in pca955x_led_set()
292 ret = pca955x_write_ls(pca955x->client, chip_ls, ls); in pca955x_led_set()
295 mutex_unlock(&pca955x->lock); in pca955x_led_set()
302 * Read the INPUT register, which contains the state of LEDs.
309 dev_err(&client->dev, "%s: reg 0x%x, err %d\n", in pca955x_read_input()
321 struct pca955x_led *led = &pca955x->leds[offset]; in pca955x_gpio_request_pin()
323 if (led->type == PCA955X_TYPE_GPIO) in pca955x_gpio_request_pin()
326 return -EBUSY; in pca955x_gpio_request_pin()
333 struct pca955x_led *led = &pca955x->leds[offset]; in pca955x_set_value()
336 return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_HIGH); in pca955x_set_value()
338 return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_LOW); in pca955x_set_value()
350 struct pca955x_led *led = &pca955x->leds[offset]; in pca955x_gpio_get_value()
354 pca955x_read_input(pca955x->client, led->led_num / 8, ®); in pca955x_gpio_get_value()
356 return !!(reg & (1 << (led->led_num % 8))); in pca955x_gpio_get_value()
363 struct pca955x_led *led = &pca955x->leds[offset]; in pca955x_gpio_direction_input()
366 return pca955x_led_set(&led->led_cdev, PCA955X_GPIO_INPUT); in pca955x_gpio_direction_input()
380 struct device_node *np = client->dev.of_node; in pca955x_pdata_of_init()
386 if (!count || count > chip->bits) in pca955x_pdata_of_init()
387 return ERR_PTR(-ENODEV); in pca955x_pdata_of_init()
389 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); in pca955x_pdata_of_init()
391 return ERR_PTR(-ENOMEM); in pca955x_pdata_of_init()
393 pdata->leds = devm_kcalloc(&client->dev, in pca955x_pdata_of_init()
394 chip->bits, sizeof(struct pca955x_led), in pca955x_pdata_of_init()
396 if (!pdata->leds) in pca955x_pdata_of_init()
397 return ERR_PTR(-ENOMEM); in pca955x_pdata_of_init()
405 if ((res != 0) || (reg >= chip->bits)) in pca955x_pdata_of_init()
409 name = child->name; in pca955x_pdata_of_init()
411 snprintf(pdata->leds[reg].name, sizeof(pdata->leds[reg].name), in pca955x_pdata_of_init()
414 pdata->leds[reg].type = PCA955X_TYPE_LED; in pca955x_pdata_of_init()
415 of_property_read_u32(child, "type", &pdata->leds[reg].type); in pca955x_pdata_of_init()
416 of_property_read_string(child, "linux,default-trigger", in pca955x_pdata_of_init()
417 &pdata->leds[reg].default_trigger); in pca955x_pdata_of_init()
420 pdata->num_leds = chip->bits; in pca955x_pdata_of_init()
438 return ERR_PTR(-ENODEV); in pca955x_pdata_of_init()
454 chip = &pca955x_chipdefs[id->driver_data]; in pca955x_probe()
458 acpi_id = acpi_match_device(pca955x_acpi_ids, &client->dev); in pca955x_probe()
460 return -ENODEV; in pca955x_probe()
461 chip = &pca955x_chipdefs[acpi_id->driver_data]; in pca955x_probe()
463 adapter = to_i2c_adapter(client->dev.parent); in pca955x_probe()
464 pdata = dev_get_platdata(&client->dev); in pca955x_probe()
472 if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) != in pca955x_probe()
473 chip->slv_addr) { in pca955x_probe()
474 dev_err(&client->dev, "invalid slave address %02x\n", in pca955x_probe()
475 client->addr); in pca955x_probe()
476 return -ENODEV; in pca955x_probe()
479 dev_info(&client->dev, "leds-pca955x: Using %s %d-bit LED driver at " in pca955x_probe()
481 client->name, chip->bits, client->addr); in pca955x_probe()
484 return -EIO; in pca955x_probe()
486 if (pdata->num_leds != chip->bits) { in pca955x_probe()
487 dev_err(&client->dev, in pca955x_probe()
488 "board info claims %d LEDs on a %d-bit chip\n", in pca955x_probe()
489 pdata->num_leds, chip->bits); in pca955x_probe()
490 return -ENODEV; in pca955x_probe()
493 pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL); in pca955x_probe()
495 return -ENOMEM; in pca955x_probe()
497 pca955x->leds = devm_kcalloc(&client->dev, in pca955x_probe()
498 chip->bits, sizeof(*pca955x_led), GFP_KERNEL); in pca955x_probe()
499 if (!pca955x->leds) in pca955x_probe()
500 return -ENOMEM; in pca955x_probe()
504 mutex_init(&pca955x->lock); in pca955x_probe()
505 pca955x->client = client; in pca955x_probe()
506 pca955x->chipdef = chip; in pca955x_probe()
508 for (i = 0; i < chip->bits; i++) { in pca955x_probe()
509 pca955x_led = &pca955x->leds[i]; in pca955x_probe()
510 pca955x_led->led_num = i; in pca955x_probe()
511 pca955x_led->pca955x = pca955x; in pca955x_probe()
512 pca955x_led->type = pdata->leds[i].type; in pca955x_probe()
514 switch (pca955x_led->type) { in pca955x_probe()
525 if (pdata->leds[i].name[0] == '\0') in pca955x_probe()
526 snprintf(pdata->leds[i].name, in pca955x_probe()
527 sizeof(pdata->leds[i].name), "%d", i); in pca955x_probe()
529 snprintf(pca955x_led->name, in pca955x_probe()
530 sizeof(pca955x_led->name), "pca955x:%s", in pca955x_probe()
531 pdata->leds[i].name); in pca955x_probe()
533 if (pdata->leds[i].default_trigger) in pca955x_probe()
534 pca955x_led->led_cdev.default_trigger = in pca955x_probe()
535 pdata->leds[i].default_trigger; in pca955x_probe()
537 pca955x_led->led_cdev.name = pca955x_led->name; in pca955x_probe()
538 pca955x_led->led_cdev.brightness_set_blocking = in pca955x_probe()
541 err = devm_led_classdev_register(&client->dev, in pca955x_probe()
542 &pca955x_led->led_cdev); in pca955x_probe()
547 err = pca955x_led_set(&pca955x_led->led_cdev, LED_OFF); in pca955x_probe()
554 err = pca955x_write_pwm(client, 0, 255 - LED_HALF); in pca955x_probe()
573 pca955x->gpio.label = "gpio-pca955x"; in pca955x_probe()
574 pca955x->gpio.direction_input = pca955x_gpio_direction_input; in pca955x_probe()
575 pca955x->gpio.direction_output = pca955x_gpio_direction_output; in pca955x_probe()
576 pca955x->gpio.set = pca955x_gpio_set_value; in pca955x_probe()
577 pca955x->gpio.get = pca955x_gpio_get_value; in pca955x_probe()
578 pca955x->gpio.request = pca955x_gpio_request_pin; in pca955x_probe()
579 pca955x->gpio.can_sleep = 1; in pca955x_probe()
580 pca955x->gpio.base = -1; in pca955x_probe()
581 pca955x->gpio.ngpio = ngpios; in pca955x_probe()
582 pca955x->gpio.parent = &client->dev; in pca955x_probe()
583 pca955x->gpio.owner = THIS_MODULE; in pca955x_probe()
585 err = devm_gpiochip_add_data(&client->dev, &pca955x->gpio, in pca955x_probe()
588 /* Use data->gpio.dev as a flag for freeing gpiochip */ in pca955x_probe()
589 pca955x->gpio.parent = NULL; in pca955x_probe()
590 dev_warn(&client->dev, "could not add gpiochip\n"); in pca955x_probe()
593 dev_info(&client->dev, "gpios %i...%i\n", in pca955x_probe()
594 pca955x->gpio.base, pca955x->gpio.base + in pca955x_probe()
595 pca955x->gpio.ngpio - 1); in pca955x_probe()
604 .name = "leds-pca955x",
614 MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>");