diff options
Diffstat (limited to 'drivers/regulator/wm8350-regulator.c')
| -rw-r--r-- | drivers/regulator/wm8350-regulator.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index c68c496b2c49..7aa35248181b 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
| @@ -1412,6 +1412,97 @@ int wm8350_register_regulator(struct wm8350 *wm8350, int reg, | |||
| 1412 | } | 1412 | } |
| 1413 | EXPORT_SYMBOL_GPL(wm8350_register_regulator); | 1413 | EXPORT_SYMBOL_GPL(wm8350_register_regulator); |
| 1414 | 1414 | ||
| 1415 | /** | ||
| 1416 | * wm8350_register_led - Register a WM8350 LED output | ||
| 1417 | * | ||
| 1418 | * @param wm8350 The WM8350 device to configure. | ||
| 1419 | * @param lednum LED device index to create. | ||
| 1420 | * @param dcdc The DCDC to use for the LED. | ||
| 1421 | * @param isink The ISINK to use for the LED. | ||
| 1422 | * @param pdata Configuration for the LED. | ||
| 1423 | * | ||
| 1424 | * The WM8350 supports the use of an ISINK together with a DCDC to | ||
| 1425 | * provide a power-efficient LED driver. This function registers the | ||
| 1426 | * regulators and instantiates the platform device for a LED. The | ||
| 1427 | * operating modes for the LED regulators must be configured using | ||
| 1428 | * wm8350_isink_set_flash(), wm8350_dcdc25_set_mode() and | ||
| 1429 | * wm8350_dcdc_set_slot() prior to calling this function. | ||
| 1430 | */ | ||
| 1431 | int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, | ||
| 1432 | struct wm8350_led_platform_data *pdata) | ||
| 1433 | { | ||
| 1434 | struct wm8350_led *led; | ||
| 1435 | struct platform_device *pdev; | ||
| 1436 | int ret; | ||
| 1437 | |||
| 1438 | if (lednum > ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) { | ||
| 1439 | dev_err(wm8350->dev, "Invalid LED index %d\n", lednum); | ||
| 1440 | return -ENODEV; | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | led = &wm8350->pmic.led[lednum]; | ||
| 1444 | |||
| 1445 | if (led->pdev) { | ||
| 1446 | dev_err(wm8350->dev, "LED %d already allocated\n", lednum); | ||
| 1447 | return -EINVAL; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | pdev = platform_device_alloc("wm8350-led", lednum); | ||
| 1451 | if (pdev == NULL) { | ||
| 1452 | dev_err(wm8350->dev, "Failed to allocate LED %d\n", lednum); | ||
| 1453 | return -ENOMEM; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | led->isink_consumer.dev = &pdev->dev; | ||
| 1457 | led->isink_consumer.supply = "led_isink"; | ||
| 1458 | led->isink_init.num_consumer_supplies = 1; | ||
| 1459 | led->isink_init.consumer_supplies = &led->isink_consumer; | ||
| 1460 | led->isink_init.constraints.min_uA = 0; | ||
| 1461 | led->isink_init.constraints.max_uA = pdata->max_uA; | ||
| 1462 | led->isink_init.constraints.valid_ops_mask = REGULATOR_CHANGE_CURRENT; | ||
| 1463 | led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL; | ||
| 1464 | ret = wm8350_register_regulator(wm8350, isink, &led->isink_init); | ||
| 1465 | if (ret != 0) { | ||
| 1466 | platform_device_put(pdev); | ||
| 1467 | return ret; | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | led->dcdc_consumer.dev = &pdev->dev; | ||
| 1471 | led->dcdc_consumer.supply = "led_vcc"; | ||
| 1472 | led->dcdc_init.num_consumer_supplies = 1; | ||
| 1473 | led->dcdc_init.consumer_supplies = &led->dcdc_consumer; | ||
| 1474 | led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL; | ||
| 1475 | ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init); | ||
| 1476 | if (ret != 0) { | ||
| 1477 | platform_device_put(pdev); | ||
| 1478 | return ret; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | switch (isink) { | ||
| 1482 | case WM8350_ISINK_A: | ||
| 1483 | wm8350->pmic.isink_A_dcdc = dcdc; | ||
| 1484 | break; | ||
| 1485 | case WM8350_ISINK_B: | ||
| 1486 | wm8350->pmic.isink_B_dcdc = dcdc; | ||
| 1487 | break; | ||
| 1488 | } | ||
| 1489 | |||
| 1490 | pdev->dev.platform_data = pdata; | ||
| 1491 | pdev->dev.parent = wm8350->dev; | ||
| 1492 | ret = platform_device_add(pdev); | ||
| 1493 | if (ret != 0) { | ||
| 1494 | dev_err(wm8350->dev, "Failed to register LED %d: %d\n", | ||
| 1495 | lednum, ret); | ||
| 1496 | platform_device_put(pdev); | ||
| 1497 | return ret; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | led->pdev = pdev; | ||
| 1501 | |||
| 1502 | return 0; | ||
| 1503 | } | ||
| 1504 | EXPORT_SYMBOL_GPL(wm8350_register_led); | ||
| 1505 | |||
| 1415 | static struct platform_driver wm8350_regulator_driver = { | 1506 | static struct platform_driver wm8350_regulator_driver = { |
| 1416 | .probe = wm8350_regulator_probe, | 1507 | .probe = wm8350_regulator_probe, |
| 1417 | .remove = wm8350_regulator_remove, | 1508 | .remove = wm8350_regulator_remove, |
