|
@@ -12,6 +12,7 @@
|
|
|
* Derived from leds-lp5521.c, leds-lp5523.c
|
|
|
*/
|
|
|
|
|
|
+#include <linux/clk.h>
|
|
|
#include <linux/delay.h>
|
|
|
#include <linux/firmware.h>
|
|
|
#include <linux/i2c.h>
|
|
@@ -21,6 +22,9 @@
|
|
|
|
|
|
#include "leds-lp55xx-common.h"
|
|
|
|
|
|
+/* External clock rate */
|
|
|
+#define LP55XX_CLK_32K 32768
|
|
|
+
|
|
|
static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)
|
|
|
{
|
|
|
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)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(lp55xx_update_bits);
|
|
|
|
|
|
+bool lp55xx_is_extclk_used(struct lp55xx_chip *chip)
|
|
|
+{
|
|
|
+ struct clk *clk;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ clk = devm_clk_get(&chip->cl->dev, "32k_clk");
|
|
|
+ if (IS_ERR(clk))
|
|
|
+ goto use_internal_clk;
|
|
|
+
|
|
|
+ err = clk_prepare_enable(clk);
|
|
|
+ if (err)
|
|
|
+ goto use_internal_clk;
|
|
|
+
|
|
|
+ if (clk_get_rate(clk) != LP55XX_CLK_32K) {
|
|
|
+ clk_disable_unprepare(clk);
|
|
|
+ goto use_internal_clk;
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K);
|
|
|
+
|
|
|
+ chip->clk = clk;
|
|
|
+ return true;
|
|
|
+
|
|
|
+use_internal_clk:
|
|
|
+ dev_info(&chip->cl->dev, "internal clock used\n");
|
|
|
+ return false;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(lp55xx_is_extclk_used);
|
|
|
+
|
|
|
int lp55xx_init_device(struct lp55xx_chip *chip)
|
|
|
{
|
|
|
struct lp55xx_platform_data *pdata;
|
|
@@ -421,6 +454,9 @@ void lp55xx_deinit_device(struct lp55xx_chip *chip)
|
|
|
{
|
|
|
struct lp55xx_platform_data *pdata = chip->pdata;
|
|
|
|
|
|
+ if (chip->clk)
|
|
|
+ clk_disable_unprepare(chip->clk);
|
|
|
+
|
|
|
if (pdata->enable)
|
|
|
pdata->enable(0);
|
|
|
|