diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-lp55xx-common.c | 36 | ||||
-rw-r--r-- | drivers/leds/leds-lp55xx-common.h | 4 |
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 | |||
24 | static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev) | 28 | static 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 | } |
358 | EXPORT_SYMBOL_GPL(lp55xx_update_bits); | 362 | EXPORT_SYMBOL_GPL(lp55xx_update_bits); |
359 | 363 | ||
364 | bool 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 | |||
387 | use_internal_clk: | ||
388 | dev_info(&chip->cl->dev, "internal clock used\n"); | ||
389 | return false; | ||
390 | } | ||
391 | EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used); | ||
392 | |||
360 | int lp55xx_init_device(struct lp55xx_chip *chip) | 393 | int 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 | */ |
84 | struct lp55xx_chip { | 84 | struct 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); | |||
117 | extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg, | 118 | extern 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 */ | ||
122 | extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip); | ||
123 | |||
120 | /* common device init/deinit functions */ | 124 | /* common device init/deinit functions */ |
121 | extern int lp55xx_init_device(struct lp55xx_chip *chip); | 125 | extern int lp55xx_init_device(struct lp55xx_chip *chip); |
122 | extern void lp55xx_deinit_device(struct lp55xx_chip *chip); | 126 | extern void lp55xx_deinit_device(struct lp55xx_chip *chip); |