#define INT_STATUS_NUM 3
-static struct resource bk_resources[] __devinitdata = {
- {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_REG,},
- {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_REG,},
- {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_REG,},
+static struct resource bk0_resources[] __devinitdata = {
+ {2, 2, "duty cycle", IORESOURCE_REG, },
+ {3, 3, "always on", IORESOURCE_REG, },
+ {3, 3, "current", IORESOURCE_REG, },
+};
+static struct resource bk1_resources[] __devinitdata = {
+ {4, 4, "duty cycle", IORESOURCE_REG, },
+ {5, 5, "always on", IORESOURCE_REG, },
+ {5, 5, "current", IORESOURCE_REG, },
+};
+static struct resource bk2_resources[] __devinitdata = {
+ {6, 6, "duty cycle", IORESOURCE_REG, },
+ {7, 7, "always on", IORESOURCE_REG, },
+ {5, 5, "current", IORESOURCE_REG, },
};
static struct resource led_resources[] __devinitdata = {
};
static struct mfd_cell bk_devs[] = {
- {"88pm860x-backlight", 0,},
- {"88pm860x-backlight", 1,},
- {"88pm860x-backlight", 2,},
+ {
+ .name = "88pm860x-backlight",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bk0_resources),
+ .resources = bk0_resources,
+ }, {
+ .name = "88pm860x-backlight",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bk1_resources),
+ .resources = bk1_resources,
+ }, {
+ .name = "88pm860x-backlight",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bk2_resources),
+ .resources = bk2_resources,
+ },
};
static struct mfd_cell led_devs[] = {
static void __devinit device_bk_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
- int ret;
- int i, j, id;
-
- if ((pdata == NULL) || (pdata->backlight == NULL))
- return;
-
- if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
- pdata->num_backlights = ARRAY_SIZE(bk_devs);
-
- for (i = 0; i < pdata->num_backlights; i++) {
- bk_devs[i].platform_data = &pdata->backlight[i];
- bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
-
- for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
- id = bk_resources[j].start;
- if (pdata->backlight[i].flags != id)
- continue;
-
- bk_devs[i].num_resources = 1;
- bk_devs[i].resources = &bk_resources[j];
- ret = mfd_add_devices(chip->dev, 0,
- &bk_devs[i], 1,
- &bk_resources[j], 0);
- if (ret < 0) {
- dev_err(chip->dev, "Failed to add "
- "backlight subdev\n");
- return;
- }
+ int ret, i;
+
+ if (pdata && pdata->backlight) {
+ if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
+ pdata->num_backlights = ARRAY_SIZE(bk_devs);
+ for (i = 0; i < pdata->num_backlights; i++) {
+ bk_devs[i].platform_data = &pdata->backlight[i];
+ bk_devs[i].pdata_size =
+ sizeof(struct pm860x_backlight_pdata);
}
}
+ ret = mfd_add_devices(chip->dev, 0, bk_devs,
+ ARRAY_SIZE(bk_devs), NULL, 0);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to add backlight subdev\n");
}
static void __devinit device_led_init(struct pm860x_chip *chip,
int port;
int pwm;
int iset;
+ int reg_duty_cycle;
+ int reg_always_on;
+ int reg_current;
};
-static inline int wled_a(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
- return ret;
-}
-
-static inline int wled_b(int port)
-{
- int ret;
-
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- return ret;
-}
-
-/* WLED2 & WLED3 share the same IDC */
-static inline int wled_idc(int port)
-{
- int ret;
-
- switch (port) {
- case PM8606_BACKLIGHT1:
- case PM8606_BACKLIGHT2:
- ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
- break;
- case PM8606_BACKLIGHT3:
- default:
- ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
- break;
- }
- return ret;
-}
-
static int backlight_power_set(struct pm860x_chip *chip, int port,
int on)
{
int ret = -EINVAL;
switch (port) {
- case PM8606_BACKLIGHT1:
+ case 0:
ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
pm8606_osc_disable(chip, WLED1_DUTY);
break;
- case PM8606_BACKLIGHT2:
+ case 1:
ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
pm8606_osc_disable(chip, WLED2_DUTY);
break;
- case PM8606_BACKLIGHT3:
+ case 2:
ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
pm8606_osc_disable(chip, WLED3_DUTY);
break;
if (brightness)
backlight_power_set(chip, data->port, 1);
- ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+ ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
if (ret < 0)
goto out;
if ((data->current_brightness == 0) && brightness) {
if (data->iset) {
- ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_current,
CURRENT_BITMASK, data->iset);
if (ret < 0)
goto out;
}
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
}
} else {
if (brightness == MAX_BRIGHTNESS) {
/* set WLED_ON bit as 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, PM8606_WLED_ON);
} else {
/* clear WLED_ON bit since it's not 100% */
- ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+ ret = pm860x_set_bits(data->i2c, data->reg_always_on,
PM8606_WLED_ON, 0);
}
}
struct pm860x_chip *chip = data->chip;
int ret;
- ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+ ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
if (ret < 0)
goto out;
data->current_brightness = ret;
static int pm860x_backlight_probe(struct platform_device *pdev)
{
struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
- struct pm860x_backlight_pdata *pdata = NULL;
+ struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
struct pm860x_backlight_data *data;
struct backlight_device *bl;
struct resource *res;
struct backlight_properties props;
char name[MFD_NAME_SIZE];
- int ret;
-
- res = platform_get_resource(pdev, IORESOURCE_REG, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "No I/O resource!\n");
- return -EINVAL;
- }
-
- pdata = pdev->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&pdev->dev, "platform data isn't assigned to "
- "backlight\n");
- return -EINVAL;
- }
+ int ret = 0;
data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- strncpy(name, res->name, MFD_NAME_SIZE);
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for duty cycle\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_duty_cycle = res->start;
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resorce for always on\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_always_on = res->start;
+ res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
+ if (!res) {
+ dev_err(&pdev->dev, "No REG resource for current\n");
+ ret = -ENXIO;
+ goto out;
+ }
+ data->reg_current = res->start;
+
+ memset(name, 0, MFD_NAME_SIZE);
+ sprintf(name, "backlight-%d", pdev->id);
+ data->port = pdev->id;
data->chip = chip;
data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
: chip->companion;
data->current_brightness = MAX_BRIGHTNESS;
- data->pwm = pdata->pwm;
- data->iset = pdata->iset;
- data->port = pdata->flags;
- if (data->port < 0) {
- dev_err(&pdev->dev, "wrong platform data is assigned");
- kfree(data);
- return -EINVAL;
+ if (pdata) {
+ data->pwm = pdata->pwm;
+ data->iset = pdata->iset;
}
memset(&props, 0, sizeof(struct backlight_properties));
/* read current backlight */
ret = pm860x_backlight_get_brightness(bl);
if (ret < 0)
- goto out;
+ goto out_brt;
backlight_update_status(bl);
return 0;
-out:
+out_brt:
backlight_device_unregister(bl);
+out:
+ devm_kfree(&pdev->dev, data);
return ret;
}