diff options
author | Kim, Milo <Milo.Kim@ti.com> | 2013-03-20 20:37:00 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2013-04-01 14:04:53 -0400 |
commit | 53b4192266436e75dea96c8ef495eadd6f3df981 (patch) | |
tree | 447691adbf313b8e58811118a43c9b76008d58d2 /drivers/leds/leds-lp55xx-common.c | |
parent | 3de1929ba61df87a0561c4f1fb7161c401fe3d04 (diff) |
leds: lp55xx: use common clock framework when external clock is used
Program execution is timed with 32768Hz clock in the LP55xx family devices.
To run LED functionalities, LP55xx devices provide two options.
One is using internal clock. The other is using external clock.
This patch enables external clock detection automatically.
If external clock is not detected, then the internal clock will be used in the
LP55xx driver.
Valid clock rate is 32768Hz in LP55xx devices.
This new API is used in each LP55xx driver like LP5521 and LP5562.
Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds/leds-lp55xx-common.c')
-rw-r--r-- | drivers/leds/leds-lp55xx-common.c | 36 |
1 files changed, 36 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 | ||