mfd: palma: support for clock
Laxman Dewangan [Tue, 11 Sep 2012 09:34:15 +0000 (14:34 +0530)]
Palma support for generating 32K Hz signal. Adding
support for this.

Change-Id: Ia0cf7c82e7b222f33c4ddb0aff748b1e12dfa273
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/131348
Reviewed-by: Automatic_Commit_Validation_User

drivers/mfd/palmas.c
include/linux/mfd/palmas.h

index 51dd11c..48f461e 100644 (file)
@@ -308,6 +308,61 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
+static u8 palmas_clk32k_control_reg[] = {
+       PALMAS_CLK32KG_CTRL,
+       PALMAS_CLK32KGAUDIO_CTRL,
+};
+
+static int palmas_resource_read(struct palmas *palmas, unsigned int reg,
+       unsigned int *dest)
+{
+       unsigned int addr = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, reg);
+
+       return regmap_read(palmas->regmap[0], addr, dest);
+}
+
+static int palmas_resource_write(struct palmas *palmas, unsigned int reg,
+       unsigned int value)
+{
+       unsigned int addr = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, reg);
+
+       return regmap_write(palmas->regmap[0], addr, value);
+}
+
+
+static void palmas_clk32k_init(struct palmas *palmas,
+       struct palmas_platform_data *pdata)
+{
+       int ret;
+       struct palmas_clk32k_init_data *clk32_idata = pdata->clk32k_init_data;
+       int data_size = pdata->clk32k_init_data_size;
+       unsigned int reg;
+       unsigned int regval;
+       int i;
+
+       if (!clk32_idata || !data_size)
+               return;
+
+       for (i = 0; i < data_size; ++i) {
+               struct palmas_clk32k_init_data *clk32_pd =  &clk32_idata[i];
+               reg = palmas_clk32k_control_reg[clk32_pd->clk32k_id];
+               ret = palmas_resource_read(palmas, reg, &regval);
+               if (ret < 0) {
+                       dev_err(palmas->dev, "Error in reading clk reg\n");
+                       return;
+               }
+               if (clk32_pd->enable)
+                       regval |=  PALMAS_CLK32KG_CTRL_MODE_ACTIVE;
+               else
+                       regval &=  ~PALMAS_CLK32KG_CTRL_MODE_ACTIVE;
+               ret = palmas_resource_write(palmas, reg, regval);
+               if (ret < 0) {
+                       dev_err(palmas->dev, "Error in writing clk reg\n");
+                       return;
+               }
+       }
+}
+
 static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
@@ -441,6 +496,9 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
        if (ret)
                goto err;
 
+
+       palmas_clk32k_init(palmas, pdata);
+
        children = kmemdup(palmas_children, sizeof(palmas_children),
                           GFP_KERNEL);
        if (!children) {
index 8efb3c4..f4464f6 100644 (file)
@@ -145,6 +145,19 @@ enum palmas_regulators {
        PALMAS_NUM_REGS,
 };
 
+enum PALMAS_CLOCK32K {
+       PALMAS_CLOCK32KG,
+       PALMAS_CLOCK32KG_AUDIO,
+
+       /* Last entry */
+       PALMAS_CLOCK32K_NR,
+};
+
+struct palmas_clk32k_init_data {
+       int clk32k_id;
+       bool enable;
+};
+
 struct palmas_pmic_platform_data {
        /* An array of pointers to regulator init data indexed by regulator
         * ID
@@ -177,6 +190,9 @@ struct palmas_platform_data {
        u8 pad1, pad2;
 
        struct palmas_pmic_platform_data *pmic_pdata;
+
+       struct palmas_clk32k_init_data  *clk32k_init_data;
+       int clk32k_init_data_size;
 };
 
 /* Define the palmas IRQ numbers */