aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorKim, Milo <Milo.Kim@ti.com>2013-03-20 20:37:00 -0400
committerBryan Wu <cooloney@gmail.com>2013-04-01 14:04:53 -0400
commit53b4192266436e75dea96c8ef495eadd6f3df981 (patch)
tree447691adbf313b8e58811118a43c9b76008d58d2 /drivers/leds
parent3de1929ba61df87a0561c4f1fb7161c401fe3d04 (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')
-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);