in leds-pca9532.c [353:465]
static int pca9532_configure(struct i2c_client *client,
struct pca9532_data *data, struct pca9532_platform_data *pdata)
{
int i, err = 0;
int gpios = 0;
u8 maxleds = data->chip_info->num_leds;
for (i = 0; i < 2; i++) {
data->pwm[i] = pdata->pwm[i];
data->psc[i] = pdata->psc[i];
i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
data->pwm[i]);
i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
data->psc[i]);
}
for (i = 0; i < data->chip_info->num_leds; i++) {
struct pca9532_led *led = &data->leds[i];
struct pca9532_led *pled = &pdata->leds[i];
led->client = client;
led->id = i;
led->type = pled->type;
switch (led->type) {
case PCA9532_TYPE_NONE:
break;
case PCA9532_TYPE_GPIO:
gpios++;
break;
case PCA9532_TYPE_LED:
if (pled->state == PCA9532_KEEP)
led->state = pca9532_getled(led);
else
led->state = pled->state;
led->name = pled->name;
led->ldev.name = led->name;
led->ldev.default_trigger = pled->default_trigger;
led->ldev.brightness = LED_OFF;
led->ldev.brightness_set_blocking =
pca9532_set_brightness;
led->ldev.blink_set = pca9532_set_blink;
err = led_classdev_register(&client->dev, &led->ldev);
if (err < 0) {
dev_err(&client->dev,
"couldn't register LED %s\n",
led->name);
goto exit;
}
pca9532_setled(led);
break;
case PCA9532_TYPE_N2100_BEEP:
BUG_ON(data->idev);
led->state = PCA9532_PWM1;
pca9532_setled(led);
data->idev = devm_input_allocate_device(&client->dev);
if (data->idev == NULL) {
err = -ENOMEM;
goto exit;
}
data->idev->name = pled->name;
data->idev->phys = "i2c/pca9532";
data->idev->id.bustype = BUS_HOST;
data->idev->id.vendor = 0x001f;
data->idev->id.product = 0x0001;
data->idev->id.version = 0x0100;
data->idev->evbit[0] = BIT_MASK(EV_SND);
data->idev->sndbit[0] = BIT_MASK(SND_BELL) |
BIT_MASK(SND_TONE);
data->idev->event = pca9532_event;
input_set_drvdata(data->idev, data);
INIT_WORK(&data->work, pca9532_input_work);
err = input_register_device(data->idev);
if (err) {
cancel_work_sync(&data->work);
data->idev = NULL;
goto exit;
}
break;
}
}
#ifdef CONFIG_LEDS_PCA9532_GPIO
if (gpios) {
data->gpio.label = "gpio-pca9532";
data->gpio.direction_input = pca9532_gpio_direction_input;
data->gpio.direction_output = pca9532_gpio_direction_output;
data->gpio.set = pca9532_gpio_set_value;
data->gpio.get = pca9532_gpio_get_value;
data->gpio.request = pca9532_gpio_request_pin;
data->gpio.can_sleep = 1;
data->gpio.base = pdata->gpio_base;
data->gpio.ngpio = data->chip_info->num_leds;
data->gpio.parent = &client->dev;
data->gpio.owner = THIS_MODULE;
err = gpiochip_add_data(&data->gpio, data);
if (err) {
/* Use data->gpio.dev as a flag for freeing gpiochip */
data->gpio.parent = NULL;
dev_warn(&client->dev, "could not add gpiochip\n");
} else {
dev_info(&client->dev, "gpios %i...%i\n",
data->gpio.base, data->gpio.base +
data->gpio.ngpio - 1);
}
}
#endif
return 0;
exit:
pca9532_destroy_devices(data, i);
return err;
}