leds: pca963x: Add support for suspend and resume
[linux-2.6-block.git] / drivers / leds / leds-pca963x.c
index 47223c850e4b4dc3bd0155352a3854c0a6e83d7c..b53905da3592017244b4da3b1651bb9f2f4feba6 100644 (file)
@@ -39,6 +39,7 @@
 #define PCA963X_LED_PWM                0x2     /* Controlled through PWM */
 #define PCA963X_LED_GRP_PWM    0x3     /* Controlled through PWM/GRPPWM */
 
+#define PCA963X_MODE1_SLEEP    0x04    /* Normal mode or Low Power mode, oscillator off */
 #define PCA963X_MODE2_OUTDRV   0x04    /* Open-drain or totem pole */
 #define PCA963X_MODE2_INVRT    0x10    /* Normal or inverted direction */
 #define PCA963X_MODE2_DMBLNK   0x20    /* Enable blinking */
@@ -380,6 +381,32 @@ err:
        return ret;
 }
 
+static int pca963x_suspend(struct device *dev)
+{
+       struct pca963x *chip = dev_get_drvdata(dev);
+       u8 reg;
+
+       reg = i2c_smbus_read_byte_data(chip->client, PCA963X_MODE1);
+       reg = reg | BIT(PCA963X_MODE1_SLEEP);
+       i2c_smbus_write_byte_data(chip->client, PCA963X_MODE1, reg);
+
+       return 0;
+}
+
+static int pca963x_resume(struct device *dev)
+{
+       struct pca963x *chip = dev_get_drvdata(dev);
+       u8 reg;
+
+       reg = i2c_smbus_read_byte_data(chip->client, PCA963X_MODE1);
+       reg = reg & ~BIT(PCA963X_MODE1_SLEEP);
+       i2c_smbus_write_byte_data(chip->client, PCA963X_MODE1, reg);
+
+       return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(pca963x_pm, pca963x_suspend, pca963x_resume);
+
 static const struct of_device_id of_pca963x_match[] = {
        { .compatible = "nxp,pca9632", },
        { .compatible = "nxp,pca9633", },
@@ -430,6 +457,7 @@ static struct i2c_driver pca963x_driver = {
        .driver = {
                .name   = "leds-pca963x",
                .of_match_table = of_pca963x_match,
+               .pm = pm_sleep_ptr(&pca963x_pm)
        },
        .probe = pca963x_probe,
        .id_table = pca963x_id,