aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp55xx-common.c36
-rw-r--r--drivers/leds/leds-lp55xx-common.h4
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 715a6027316f..ba34199dc3d9 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -12,6 +12,7 @@
12 * Derived from leds-lp5521.c, leds-lp5523.c 12 * Derived from leds-lp5521.c, leds-lp5523.c
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/firmware.h> 17#include <linux/firmware.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
@@ -21,6 +22,9 @@
21 22
22#include "leds-lp55xx-common.h" 23#include "leds-lp55xx-common.h"
23 24
25/* External clock rate */
26#define LP55XX_CLK_32K 32768
27
24static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev) 28static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
25{ 29{
26 return container_of(cdev, struct lp55xx_led, cdev); 30 return container_of(cdev, struct lp55xx_led, cdev);
@@ -357,6 +361,35 @@ int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, u8 mask, u8 val)
357} 361}
358EXPORT_SYMBOL_GPL(lp55xx_update_bits); 362EXPORT_SYMBOL_GPL(lp55xx_update_bits);
359 363
364bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
365{
366 struct clk *clk;
367 int err;
368
369 clk = devm_clk_get(&chip->cl->dev, "32k_clk");
370 if (IS_ERR(clk))
371 goto use_internal_clk;
372
373 err = clk_prepare_enable(clk);
374 if (err)
375 goto use_internal_clk;
376
377 if (clk_get_rate(clk) != LP55XX_CLK_32K) {
378 clk_disable_unprepare(clk);
379 goto use_internal_clk;
380 }
381
382 dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K);
383
384 chip->clk = clk;
385 return true;
386
387use_internal_clk:
388 dev_info(&chip->cl->dev, "internal clock used\n");
389 return false;
390}
391EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
392
360int lp55xx_init_device(struct lp55xx_chip *chip) 393int lp55xx_init_device(struct lp55xx_chip *chip)
361{ 394{
362 struct lp55xx_platform_data *pdata; 395 struct lp55xx_platform_data *pdata;
@@ -421,6 +454,9 @@ void lp55xx_deinit_device(struct lp55xx_chip *chip)
421{ 454{
422 struct lp55xx_platform_data *pdata = chip->pdata; 455 struct lp55xx_platform_data *pdata = chip->pdata;
423 456
457 if (chip->clk)
458 clk_disable_unprepare(chip->clk);
459
424 if (pdata->enable) 460 if (pdata->enable)
425 pdata->enable(0); 461 pdata->enable(0);
426 462
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index ece4761a1302..fa6a078bf547 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -83,6 +83,7 @@ struct lp55xx_device_config {
83 */ 83 */
84struct lp55xx_chip { 84struct lp55xx_chip {
85 struct i2c_client *cl; 85 struct i2c_client *cl;
86 struct clk *clk;
86 struct lp55xx_platform_data *pdata; 87 struct lp55xx_platform_data *pdata;
87 struct mutex lock; /* lock for user-space interface */ 88 struct mutex lock; /* lock for user-space interface */
88 int num_leds; 89 int num_leds;
@@ -117,6 +118,9 @@ extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val);
117extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, 118extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,
118 u8 mask, u8 val); 119 u8 mask, u8 val);
119 120
121/* external clock detection */
122extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
123
120/* common device init/deinit functions */ 124/* common device init/deinit functions */
121extern int lp55xx_init_device(struct lp55xx_chip *chip); 125extern int lp55xx_init_device(struct lp55xx_chip *chip);
122extern void lp55xx_deinit_device(struct lp55xx_chip *chip); 126extern void lp55xx_deinit_device(struct lp55xx_chip *chip);