aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/wm8350-regulator.c91
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}
1413EXPORT_SYMBOL_GPL(wm8350_register_regulator); 1413EXPORT_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 */
1431int 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}
1504EXPORT_SYMBOL_GPL(wm8350_register_led);
1505
1415static struct platform_driver wm8350_regulator_driver = { 1506static 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,