From: "Ying-Chun Liu (PaulLiu)" <paul....@linaro.org>

Add DA9052 mfd driver from Dialog.
Modify Kconfig/Makefile for DA9052 mfd driver.

Signed-off-by: Zhou Jingyu <jingyu.z...@freescale.com>
Acked-by: Lily Zhang <r58...@freescale.com>
Signed-off-by: Ying-Chun Liu (PaulLiu) <paul....@linaro.org>
---
 drivers/mfd/Kconfig       |   37 +++
 drivers/mfd/Makefile      |    2 +
 drivers/mfd/da9052-core.c |  536 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/mfd/da9052-i2c.c  |  378 ++++++++++++++++++++++++++++++++
 drivers/mfd/da9052-spi.c  |  402 +++++++++++++++++++++++++++++++++
 5 files changed, 1355 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/da9052-core.c
 create mode 100644 drivers/mfd/da9052-i2c.c
 create mode 100644 drivers/mfd/da9052-spi.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 0f09c05..a3d0568 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -483,6 +483,43 @@ config PCF50633_GPIO
         Say yes here if you want to include support GPIO for pins on
         the PCF50633 chip.
 
+config PMIC_DIALOG
+       bool "Support Dialog Semiconductor PMIC"
+       depends on I2C=y
+       depends on SPI=y
+       select MFD_CORE
+       help
+       Support for Dialog semiconductor PMIC chips.
+       Use the options provided to support the desired PMIC's.
+choice
+       prompt "Chip Type"
+       depends on PMIC_DIALOG
+config PMIC_DA9052
+       bool "Support Dialog Semiconductor DA9052 PMIC"
+       help
+       Support for Dialog semiconductor DA9052 PMIC with inbuilt
+       SPI & I2C connectivities.
+       This driver provides common support for accessing  the device,
+       additional drivers must be enabled in order to use the
+       functionality of the device.
+config PMIC_DA9053AA
+       bool "Support Dialog Semiconductor DA9053 AA PMIC"
+       help
+       Support for Dialog semiconductor DA9053 AA PMIC with inbuilt
+       SPI & I2C connectivities.
+       This driver provides common support for accessing  the device,
+       additional drivers must be enabled in order to use the
+       functionality of the device.
+config PMIC_DA9053Bx
+       bool "Support Dialog Semiconductor DA9053 BA/BB PMIC"
+       help
+       Support for Dialog semiconductor DA9053 BA/BB PMIC with inbuilt
+       SPI & I2C connectivities.
+       This driver provides common support for accessing  the device,
+       additional drivers must be enabled in order to use the
+       functionality of the device.
+endchoice
+
 config MFD_MC13783
        tristate
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index efe3cc3..d30b69c 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -94,3 +94,5 @@ obj-$(CONFIG_MFD_OMAP_USB_HOST)       += omap-usb-host.o
 obj-$(CONFIG_MFD_PM8921_CORE)  += pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ)   += pm8xxx-irq.o
 obj-$(CONFIG_MFD_TPS65910)     += tps65910.o tps65910-irq.o
+da9052-objs                    := da9052-spi.o da9052-i2c.o da9052-core.o
+obj-$(CONFIG_PMIC_DIALOG)      += da9052.o
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
new file mode 100644
index 0000000..002cf50
--- /dev/null
+++ b/drivers/mfd/da9052-core.c
@@ -0,0 +1,536 @@
+/*
+ * da9052-core.c  --  Device access for Dialog DA9052
+ *
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * Author: Dialog Semiconductor Ltd <dc...@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/mfd/core.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/semaphore.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/adc.h>
+
+#define SUCCESS                0
+#define FAILURE                1
+
+struct da9052_eh_nb eve_nb_array[EVE_CNT];
+static struct da9052_ssc_ops ssc_ops;
+struct mutex manconv_lock;
+static struct semaphore eve_nb_array_lock;
+
+void da9052_lock(struct da9052 *da9052)
+{
+       mutex_lock(&da9052->ssc_lock);
+}
+EXPORT_SYMBOL(da9052_lock);
+
+void da9052_unlock(struct da9052 *da9052)
+{
+       mutex_unlock(&da9052->ssc_lock);
+}
+EXPORT_SYMBOL(da9052_unlock);
+
+int da9052_ssc_write(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg)
+{
+       int ret = 0;
+
+       /* Reg address should be a valid address on PAGE0 or PAGE1 */
+       if ((sscmsg->addr < DA9052_PAGE0_REG_START) ||
+       (sscmsg->addr > DA9052_PAGE1_REG_END) ||
+       ((sscmsg->addr > DA9052_PAGE0_REG_END) &&
+       (sscmsg->addr < DA9052_PAGE1_REG_START)))
+               return INVALID_REGISTER;
+
+       ret = ssc_ops.write(da9052, sscmsg);
+
+       /* Update local cache if required */
+       if (!ret) {
+               /* Check if this register is Non-volatile*/
+               if (da9052->ssc_cache[sscmsg->addr].type != VOLATILE) {
+                       /* Update value */
+                       da9052->ssc_cache[sscmsg->addr].val = sscmsg->data;
+                       /* Make this cache entry valid */
+                       da9052->ssc_cache[sscmsg->addr].status = VALID;
+               }
+       }
+
+       return ret;
+}
+
+int da9052_ssc_read(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg)
+{
+       int ret = 0;
+
+       /* Reg addr should be a valid address on PAGE0 or PAGE1 */
+       if ((sscmsg->addr < DA9052_PAGE0_REG_START) ||
+       (sscmsg->addr > DA9052_PAGE1_REG_END) ||
+       ((sscmsg->addr > DA9052_PAGE0_REG_END) &&
+       (sscmsg->addr < DA9052_PAGE1_REG_START)))
+               return INVALID_REGISTER;
+
+       /*
+        * Check if this is a Non-volatile register, if yes then return value -
+        * from cache instead of actual reading from hardware. Before reading -
+        * cache entry, make sure that the entry is valid
+        */
+       /* The read request is for Non-volatile register */
+       /* Check if we have valid cached value for this */
+       if (da9052->ssc_cache[sscmsg->addr].status == VALID) {
+               /* We have valid cached value, copy this value */
+               sscmsg->data = da9052->ssc_cache[sscmsg->addr].val;
+
+               return 0;
+       }
+
+       ret = ssc_ops.read(da9052, sscmsg);
+
+       /* Update local cache if required */
+       if (!ret) {
+               /* Check if this register is Non-volatile*/
+               if (da9052->ssc_cache[sscmsg->addr].type != VOLATILE) {
+                       /* Update value */
+                       da9052->ssc_cache[sscmsg->addr].val = sscmsg->data;
+                       /* Make this cache entry valid */
+                       da9052->ssc_cache[sscmsg->addr].status = VALID;
+               }
+       }
+
+       return ret;
+}
+
+int da9052_ssc_write_many(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg,
+                               int msg_no)
+{
+       int ret = 0;
+       int cnt = 0;
+
+       /* Check request size */
+       if (msg_no > MAX_READ_WRITE_CNT)
+               return -EIO;
+
+       ret = ssc_ops.write_many(da9052, sscmsg, msg_no);
+       /* Update local cache, if required */
+       for (cnt = 0; cnt < msg_no; cnt++) {
+               /* Check if this register is Non-volatile*/
+               if (da9052->ssc_cache[sscmsg[cnt].addr].type != VOLATILE) {
+                       /* Update value */
+                       da9052->ssc_cache[sscmsg[cnt].addr].val =
+                       sscmsg[cnt].data;
+                       /* Make this cache entry valid */
+                       da9052->ssc_cache[sscmsg[cnt].addr].status = VALID;
+               }
+       }
+       return ret;
+}
+
+int da9052_ssc_read_many(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg,
+                       int msg_no)
+{
+       int ret = 0;
+       int cnt = 0;
+
+       /* Check request size */
+       if (msg_no > MAX_READ_WRITE_CNT)
+               return -EIO;
+
+       ret = ssc_ops.read_many(da9052, sscmsg, msg_no);
+       /* Update local cache, if required */
+       for (cnt = 0; cnt < msg_no; cnt++) {
+               /* Check if this register is Non-volatile*/
+               if (da9052->ssc_cache[sscmsg[cnt].addr].type
+                       != VOLATILE) {
+                       /* Update value */
+                       da9052->ssc_cache[sscmsg[cnt].addr].val =
+                       sscmsg[cnt].data;
+                       /* Make this cache entry valid */
+                       da9052->ssc_cache[sscmsg[cnt].addr].status = VALID;
+               }
+       }
+       return ret;
+}
+
+static irqreturn_t da9052_eh_isr(int irq, void *dev_id)
+{
+       struct da9052 *da9052 = dev_id;
+       /* Schedule work to be done */
+       schedule_work(&da9052->eh_isr_work);
+       /* Disable IRQ */
+       disable_irq_nosync(da9052->irq);
+       return IRQ_HANDLED;
+}
+
+int eh_register_nb(struct da9052 *da9052, struct da9052_eh_nb *nb)
+{
+
+       if (nb == NULL) {
+               printk(KERN_INFO "EH REGISTER FUNCTION FAILED\n");
+               return -EINVAL;
+       }
+
+       if (nb->eve_type >= EVE_CNT) {
+               printk(KERN_INFO "Invalid DA9052 Event Type\n");
+               return -EINVAL;
+       }
+
+       /* Initialize list head inside notifier block */
+       INIT_LIST_HEAD(&nb->nb_list);
+
+       /* Acquire NB array lock */
+       if (down_interruptible(&eve_nb_array_lock))
+               return -EAGAIN;
+
+       /* Add passed NB to corresponding EVENT list */
+       list_add_tail(&nb->nb_list, &(eve_nb_array[nb->eve_type].nb_list));
+
+       /* Release NB array lock */
+       up(&eve_nb_array_lock);
+
+       return 0;
+}
+
+int eh_unregister_nb(struct da9052 *da9052, struct da9052_eh_nb *nb)
+{
+
+       if (nb == NULL)
+               return -EINVAL;
+
+       /* Acquire nb array lock */
+       if (down_interruptible(&eve_nb_array_lock))
+               return -EAGAIN;
+
+       /* Remove passed NB from list */
+       list_del_init(&(nb->nb_list));
+
+       /* Release NB array lock */
+       up(&eve_nb_array_lock);
+
+       return 0;
+}
+
+static int process_events(struct da9052 *da9052, int events_sts)
+{
+
+       int cnt = 0;
+       int tmp_events_sts = 0;
+       unsigned char event = 0;
+
+       struct list_head *ptr;
+       struct da9052_eh_nb *nb_ptr;
+
+       /* Now we have retrieved all events, process them one by one */
+       for (cnt = 0; cnt < EVE_CNT; cnt++) {
+               /*
+                * Starting with highest priority event,
+                * traverse through all event
+                */
+               tmp_events_sts = events_sts;
+
+               /* Find the event associated with higher priority */
+               event = cnt;
+
+               /* Check if interrupt is received for this event */
+               if (!((tmp_events_sts >> cnt) & 0x1))
+                       /* Event bit is not set for this event */
+                       /* Move to next event */
+                       continue;
+
+               if (event == PEN_DOWN_EVE) {
+                       if (list_empty(&(eve_nb_array[event].nb_list)))
+                               continue;
+               }
+
+               /* Event bit is set, execute all registered call backs */
+               if (down_interruptible(&eve_nb_array_lock)) {
+                       printk(KERN_CRIT "Can't acquire eve_nb_array_lock\n");
+                       return -EIO;
+               }
+
+               list_for_each(ptr, &(eve_nb_array[event].nb_list)) {
+                       /*
+                        * nb_ptr will point to the structure in which
+                        * nb_list is embedded
+                        */
+                       nb_ptr = list_entry(ptr, struct da9052_eh_nb, nb_list);
+                       nb_ptr->call_back(nb_ptr, events_sts);
+               }
+               up(&eve_nb_array_lock);
+       }
+       return 0;
+}
+
+void eh_workqueue_isr(struct work_struct *work)
+{
+       struct da9052 *da9052 =
+               container_of(work, struct da9052, eh_isr_work);
+
+       struct da9052_ssc_msg eve_data[4];
+       struct da9052_ssc_msg eve_mask_data[4];
+       int events_sts, ret;
+       u32 mask;
+       unsigned char cnt = 0;
+
+       /* nIRQ is asserted, read event registeres to know what happened */
+       events_sts = 0;
+       mask = 0;
+
+       /* Prepare ssc message to read all four event registers */
+       for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) {
+               eve_data[cnt].addr = (DA9052_EVENTA_REG + cnt);
+               eve_data[cnt].data = 0;
+       }
+
+       /* Prepare ssc message to read all four event registers */
+       for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++) {
+               eve_mask_data[cnt].addr = (DA9052_IRQMASKA_REG + cnt);
+               eve_mask_data[cnt].data = 0;
+       }
+
+       /* Now read all event and mask registers */
+       da9052_lock(da9052);
+
+       ret = da9052_ssc_read_many(da9052, eve_data, DA9052_EVE_REGISTERS);
+       if (ret) {
+               enable_irq(da9052->irq);
+               da9052_unlock(da9052);
+               return;
+       }
+
+       ret = da9052_ssc_read_many(da9052, eve_mask_data, DA9052_EVE_REGISTERS);
+       if (ret) {
+               enable_irq(da9052->irq);
+               da9052_unlock(da9052);
+               return;
+       }
+       /* Collect all events */
+       for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++)
+               events_sts |= (eve_data[cnt].data << (DA9052_EVE_REGISTER_SIZE
+                                                       * cnt));
+       /* Collect all mask */
+       for (cnt = 0; cnt < DA9052_EVE_REGISTERS; cnt++)
+               mask |= (eve_mask_data[cnt].data << (DA9052_EVE_REGISTER_SIZE
+                                               * cnt));
+       events_sts &= ~mask;
+       da9052_unlock(da9052);
+
+       /* Check if we really got any event */
+       if (events_sts == 0) {
+               enable_irq(da9052->irq);
+               da9052_unlock(da9052);
+               return;
+       }
+
+       /* Process all events occurred */
+       process_events(da9052, events_sts);
+
+       da9052_lock(da9052);
+       /* Now clear EVENT registers */
+       for (cnt = 0; cnt < 4; cnt++) {
+               if (eve_data[cnt].data) {
+                       ret = da9052_ssc_write(da9052, &eve_data[cnt]);
+                       if (ret) {
+                               enable_irq(da9052->irq);
+                               da9052_unlock(da9052);
+                               return;
+                       }
+               }
+       }
+       da9052_unlock(da9052);
+
+       /*
+       * This delay is necessary to avoid hardware fake interrupts
+       * from DA9052.
+       */
+#if defined  CONFIG_PMIC_DA9052 || defined  CONFIG_PMIC_DA9053AA
+       udelay(50);
+#endif
+       /* Enable HOST interrupt */
+       enable_irq(da9052->irq);
+}
+
+static void da9052_eh_restore_irq(struct da9052 *da9052)
+{
+       /* Put your platform and board specific code here */
+       free_irq(da9052->irq, NULL);
+}
+
+static int da9052_add_subdevice_pdata(struct da9052 *da9052,
+               const char *name, void *pdata, size_t pdata_size)
+{
+       struct mfd_cell cell = {
+               .name = name,
+               .platform_data = pdata,
+               .pdata_size = pdata_size,
+       };
+       return mfd_add_devices(da9052->dev, -1, &cell, 1, NULL, 0);
+}
+
+static int da9052_add_subdevice(struct da9052 *da9052, const char *name)
+{
+       return da9052_add_subdevice_pdata(da9052, name, NULL, 0);
+}
+
+static int add_da9052_devices(struct da9052 *da9052)
+{
+       s32 ret = 0;
+       struct da9052_platform_data *pdata = da9052->dev->platform_data;
+       struct da9052_leds_platform_data leds_data = {
+                       .num_leds = pdata->led_data->num_leds,
+                       .led = pdata->led_data->led,
+       };
+       struct da9052_regulator_platform_data regulator_pdata = {
+               .regulators = pdata->regulators,
+       };
+
+       struct da9052_tsi_platform_data tsi_data = *(pdata->tsi_data);
+
+       if (pdata && pdata->init) {
+               ret = pdata->init(da9052);
+               if (ret != 0)
+                       return ret;
+       } else
+               pr_err("No platform initialisation supplied\n");
+
+       ret = da9052_add_subdevice(da9052, "da9052-rtc");
+       if (ret)
+               return ret;
+       ret = da9052_add_subdevice(da9052, "da9052-onkey");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "WLED-1");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "WLED-2");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "WLED-3");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "da9052-adc");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "da9052-wdt");
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice_pdata(da9052, "da9052-leds",
+                               &leds_data, sizeof(leds_data));
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice_pdata(da9052, "da9052-regulator",
+               &regulator_pdata, sizeof(regulator_pdata));
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice_pdata(da9052, "da9052-tsi",
+                               &tsi_data, sizeof(tsi_data));
+       if (ret)
+               return ret;
+
+       ret = da9052_add_subdevice(da9052, "da9052-bat");
+       if (ret)
+               return ret;
+
+       return ret;
+}
+
+int da9052_ssc_init(struct da9052 *da9052)
+{
+       int cnt;
+       struct da9052_platform_data *pdata;
+       struct da9052_ssc_msg ssc_msg;
+
+       /* Initialize eve_nb_array */
+       for (cnt = 0; cnt < EVE_CNT; cnt++)
+               INIT_LIST_HEAD(&(eve_nb_array[cnt].nb_list));
+
+       /* Initialize mutex required for ADC Manual read */
+       mutex_init(&manconv_lock);
+
+       /* Initialize NB array lock */
+       sema_init(&eve_nb_array_lock, 1);
+
+       /* Assign the read-write function pointers */
+       da9052->read = da9052_ssc_read;
+       da9052->write = da9052_ssc_write;
+       da9052->read_many = da9052_ssc_read_many;
+       da9052->write_many = da9052_ssc_write_many;
+
+       if (SPI  == da9052->connecting_device && ssc_ops.write == NULL) {
+               /* Assign the read/write pointers to SPI/read/write */
+               ssc_ops.write = da9052_spi_write;
+               ssc_ops.read = da9052_spi_read;
+               ssc_ops.write_many = da9052_spi_write_many;
+               ssc_ops.read_many = da9052_spi_read_many;
+       } else if (I2C  == da9052->connecting_device
+                  && ssc_ops.write == NULL) {
+               /* Assign the read/write pointers to SPI/read/write */
+               ssc_ops.write = da9052_i2c_write;
+               ssc_ops.read = da9052_i2c_read;
+               ssc_ops.write_many = da9052_i2c_write_many;
+               ssc_ops.read_many = da9052_i2c_read_many;
+       } else
+               return -1;
+       /* Assign the EH notifier block register/de-register functions */
+       da9052->register_event_notifier = eh_register_nb;
+       da9052->unregister_event_notifier = eh_unregister_nb;
+
+       /* Initialize ssc lock */
+       mutex_init(&da9052->ssc_lock);
+
+       pdata = da9052->dev->platform_data;
+       add_da9052_devices(da9052);
+
+       INIT_WORK(&da9052->eh_isr_work, eh_workqueue_isr);
+       ssc_msg.addr = DA9052_IRQMASKA_REG;
+       ssc_msg.data = 0xff;
+       da9052->write(da9052, &ssc_msg);
+       ssc_msg.addr = DA9052_IRQMASKC_REG;
+       ssc_msg.data = 0xff;
+       da9052->write(da9052, &ssc_msg);
+       if (request_irq(da9052->irq, da9052_eh_isr, IRQ_TYPE_LEVEL_LOW,
+               DA9052_EH_DEVICE_NAME, da9052))
+               return -EIO;
+       enable_irq_wake(da9052->irq);
+
+       return 0;
+}
+
+void da9052_ssc_exit(struct da9052 *da9052)
+{
+       printk(KERN_INFO "DA9052: Unregistering SSC device.\n");
+       mutex_destroy(&manconv_lock);
+       /* Restore IRQ line */
+       da9052_eh_restore_irq(da9052);
+       free_irq(da9052->irq, NULL);
+       mutex_destroy(&da9052->ssc_lock);
+       mutex_destroy(&da9052->eve_nb_lock);
+       return;
+}
+
+MODULE_AUTHOR("Dialog Semiconductor Ltd <dc...@diasemi.com>");
+MODULE_DESCRIPTION("DA9052 MFD Core");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DA9052_SSC_DEVICE_NAME);
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
new file mode 100644
index 0000000..5fd966a
--- /dev/null
+++ b/drivers/mfd/da9052-i2c.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052-i2c.c: I2C SSC (Synchronous Serial Communication) driver for DA9052
+ */
+
+#include <linux/device.h>
+#include <linux/mfd/core.h>
+#include <linux/i2c.h>
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+static struct da9052 *da9052_i2c;
+
+#define I2C_CONNECTED 0
+
+static int da9052_i2c_is_connected(void)
+{
+
+       struct da9052_ssc_msg msg;
+
+       /* printk("Entered da9052_i2c_is_connected.............\n"); */
+
+       msg.addr = DA9052_INTERFACE_REG;
+
+       /* Test spi connectivity by performing read of the GPIO_0-1 register */
+       if (0 != da9052_i2c_read(da9052_i2c, &msg)) {
+               printk(KERN_DEBUG "da9052_i2c_is_connected - "\
+                      "i2c read failed.............\n");
+               return -1;
+       } else {
+               printk(KERN_DEBUG "da9052_i2c_is_connected - "\
+                      "i2c read success..............\n");
+               return 0;
+       }
+
+}
+
+static int __devinit da9052_i2c_probe(struct i2c_client *client,
+       const struct i2c_device_id *id)
+{
+       struct i2c_adapter *adapter;
+       /* printk("\n\tEntered da9052_i2c_is_probe.............\n"); */
+
+       da9052_i2c = kzalloc(sizeof(struct da9052), GFP_KERNEL);
+
+       if (!da9052_i2c)
+               return -ENOMEM;
+
+       /* Get the bus driver handler */
+       adapter = to_i2c_adapter(client->dev.parent);
+
+       /* Check i2c bus driver supports byte data transfer */
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+               dev_info(&client->dev,\
+               "Error in %s:i2c_check_functionality\n", __func__);
+               return -ENODEV;
+       }
+
+       /* Store handle to i2c client */
+       da9052_i2c->i2c_client = client;
+       da9052_i2c->irq = client->irq;
+
+       da9052_i2c->dev = &client->dev;
+
+       /* Initialize i2c data structure here*/
+       da9052_i2c->adapter = adapter;
+
+       /* host i2c driver looks only first 7 bits for the slave address */
+       da9052_i2c->slave_addr = DA9052_I2C_ADDR >> 1;
+
+       /* Store the i2c client data */
+       i2c_set_clientdata(client, da9052_i2c);
+
+       /* Validate I2C connectivity */
+       if (I2C_CONNECTED  == da9052_i2c_is_connected()) {
+               /* I2C is connected */
+               da9052_i2c->connecting_device = I2C;
+               if (0 != da9052_ssc_init(da9052_i2c))
+                       return -ENODEV;
+       } else {
+               return -ENODEV;
+       }
+
+       /* printk("Exiting da9052_i2c_probe.....\n"); */
+
+       return 0;
+}
+
+static int da9052_i2c_remove(struct i2c_client *client)
+{
+
+       struct da9052 *da9052 = i2c_get_clientdata(client);
+
+       mfd_remove_devices(da9052->dev);
+       kfree(da9052);
+       return 0;
+}
+
+int da9052_i2c_write(struct da9052 *da9052, struct da9052_ssc_msg *msg)
+{
+       struct i2c_msg i2cmsg;
+       unsigned char buf[2] = {0};
+       int ret = 0;
+
+       /* Copy the ssc msg to local character buffer */
+       buf[0] = msg->addr;
+       buf[1] = msg->data;
+
+       /*Construct a i2c msg for a da9052 driver ssc message request */
+       i2cmsg.addr  = da9052->slave_addr;
+       i2cmsg.len   = 2;
+       i2cmsg.buf   = buf;
+
+       /* To write the data on I2C set flag to zero */
+       i2cmsg.flags = 0;
+
+       /* Start the i2c transfer by calling host i2c driver function */
+       ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
+
+       if (ret < 0) {
+               dev_info(&da9052->i2c_client->dev,\
+               "_%s:master_xfer Failed!!\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+int da9052_i2c_read(struct da9052 *da9052, struct da9052_ssc_msg *msg)
+{
+
+       /*Get the da9052_i2c client details*/
+       unsigned char buf[2] = {0, 0};
+       struct i2c_msg i2cmsg[2];
+       int ret = 0;
+
+       /* Copy SSC Msg to local character buffer */
+       buf[0] = msg->addr;
+
+       /*Construct a i2c msg for a da9052 driver ssc message request */
+       i2cmsg[0].addr  = da9052->slave_addr ;
+       i2cmsg[0].len   = 1;
+       i2cmsg[0].buf   = &buf[0];
+
+       /*To write the data on I2C set flag to zero */
+       i2cmsg[0].flags = 0;
+
+       /* Read the data from da9052*/
+       /*Construct a i2c msg for a da9052 driver ssc message request */
+       i2cmsg[1].addr  = da9052->slave_addr ;
+       i2cmsg[1].len   = 1;
+       i2cmsg[1].buf   = &buf[1];
+
+       /*To read the data on I2C set flag to I2C_M_RD */
+       i2cmsg[1].flags = I2C_M_RD;
+
+       /* Start the i2c transfer by calling host i2c driver function */
+       ret = i2c_transfer(da9052->adapter, i2cmsg, 2);
+       if (ret < 0) {
+               dev_info(&da9052->i2c_client->dev,\
+               "2 - %s:master_xfer Failed!!\n", __func__);
+               return ret;
+       }
+
+       msg->data = *i2cmsg[1].buf;
+
+       return 0;
+}
+
+int da9052_i2c_write_many(struct da9052 *da9052,
+       struct da9052_ssc_msg *sscmsg, int msg_no)
+{
+
+       struct i2c_msg i2cmsg;
+       unsigned char data_buf[MAX_READ_WRITE_CNT+1];
+       struct da9052_ssc_msg ctrlb_msg;
+       struct da9052_ssc_msg *msg_queue = sscmsg;
+       int ret = 0;
+       /* Flag to check if requested registers are contiguous */
+       unsigned char cont_data = 1;
+       unsigned char cnt = 0;
+
+       /* Check if requested registers are contiguous */
+       for (cnt = 1; cnt < msg_no; cnt++) {
+               if ((msg_queue[cnt].addr - msg_queue[cnt-1].addr) != 1) {
+                       /* Difference is not 1, i.e. non-contiguous registers */
+                       cont_data = 0;
+                       break;
+               }
+       }
+
+       if (cont_data == 0) {
+               /* Requested registers are non-contiguous */
+               for (cnt = 0; cnt < msg_no; cnt++) {
+                       ret = da9052->write(da9052, &msg_queue[cnt]);
+                       if (ret != 0)
+                               return ret;
+               }
+               return 0;
+       }
+       /*
+       *  Requested registers are contiguous
+       * or PAGE WRITE sequence of I2C transactions is as below
+       * (slave_addr + reg_addr + data_1 + data_2 + ...)
+       * First read current WRITE MODE via CONTROL_B register of DA9052
+       */
+       ctrlb_msg.addr = DA9052_CONTROLB_REG;
+       ctrlb_msg.data = 0x0;
+       ret = da9052->read(da9052, &ctrlb_msg);
+
+       if (ret != 0)
+               return ret;
+
+       /* Check if PAGE WRITE mode is set */
+       if (ctrlb_msg.data & DA9052_CONTROLB_WRITEMODE) {
+               /* REPEAT WRITE mode is configured */
+               /* Now set DA9052 into PAGE WRITE mode */
+               ctrlb_msg.data &= ~DA9052_CONTROLB_WRITEMODE;
+               ret = da9052->write(da9052, &ctrlb_msg);
+
+               if (ret != 0)
+                       return ret;
+       }
+
+        /* Put first register address */
+       data_buf[0] = msg_queue[0].addr;
+
+       for (cnt = 0; cnt < msg_no; cnt++)
+               data_buf[cnt+1] = msg_queue[cnt].data;
+
+       /* Construct a i2c msg for PAGE WRITE */
+       i2cmsg.addr  = da9052->slave_addr ;
+       /* First register address + all data*/
+       i2cmsg.len   = (msg_no + 1);
+       i2cmsg.buf   = data_buf;
+
+       /*To write the data on I2C set flag to zero */
+       i2cmsg.flags = 0;
+
+       /* Start the i2c transfer by calling host i2c driver function */
+       ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
+       if (ret < 0) {
+               dev_info(&da9052->i2c_client->dev,\
+               "1 - i2c_transfer function falied in [%s]!!!\n", __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+int da9052_i2c_read_many(struct da9052 *da9052,
+       struct da9052_ssc_msg *sscmsg, int msg_no)
+{
+
+       struct i2c_msg i2cmsg;
+       unsigned char data_buf[MAX_READ_WRITE_CNT];
+       struct da9052_ssc_msg *msg_queue = sscmsg;
+       int ret = 0;
+       /* Flag to check if requested registers are contiguous */
+       unsigned char cont_data = 1;
+       unsigned char cnt = 0;
+
+       /* Check if requested registers are contiguous */
+       for (cnt = 1; cnt < msg_no; cnt++) {
+               if ((msg_queue[cnt].addr - msg_queue[cnt-1].addr) != 1) {
+                       /* Difference is not 1, i.e. non-contiguous registers */
+                       cont_data = 0;
+                       break;
+               }
+       }
+
+       if (cont_data == 0) {
+               /* Requested registers are non-contiguous */
+               for (cnt = 0; cnt < msg_no; cnt++) {
+                       ret = da9052->read(da9052, &msg_queue[cnt]);
+                       if (ret != 0) {
+                               dev_info(&da9052->i2c_client->dev,\
+                               "Error in %s", __func__);
+                               return ret;
+                       }
+               }
+               return 0;
+       }
+
+       /*
+       * We want to perform PAGE READ via I2C
+       * For PAGE READ sequence of I2C transactions is as below
+       * (slave_addr + reg_addr) + (slave_addr + data_1 + data_2 + ...)
+       */
+       /* Copy address of first register */
+       data_buf[0] = msg_queue[0].addr;
+
+       /* Construct a i2c msg for first transaction of PAGE READ i.e. write */
+       i2cmsg.addr  = da9052->slave_addr ;
+       i2cmsg.len   = 1;
+       i2cmsg.buf   = data_buf;
+
+       /*To write the data on I2C set flag to zero */
+       i2cmsg.flags = 0;
+
+       /* Start the i2c transfer by calling host i2c driver function */
+       ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
+       if (ret < 0) {
+               dev_info(&da9052->i2c_client->dev,\
+               "1 - i2c_transfer function falied in [%s]!!!\n", __func__);
+               return ret;
+       }
+
+       /* Now Read the data from da9052 */
+       /* Construct a i2c msg for second transaction of PAGE READ i.e. read */
+       i2cmsg.addr  = da9052->slave_addr ;
+       i2cmsg.len   = msg_no;
+       i2cmsg.buf   = data_buf;
+
+       /*To read the data on I2C set flag to I2C_M_RD */
+       i2cmsg.flags = I2C_M_RD;
+
+       /* Start the i2c transfer by calling host i2c driver function */
+       ret = i2c_transfer(da9052->adapter,
+               &i2cmsg, 1);
+       if (ret < 0) {
+               dev_info(&da9052->i2c_client->dev,\
+               "2 - i2c_transfer function falied in [%s]!!!\n", __func__);
+               return ret;
+       }
+
+       /* Gather READ data */
+       for (cnt = 0; cnt < msg_no; cnt++)
+               sscmsg[cnt].data = data_buf[cnt];
+
+       return 0;
+}
+
+static struct i2c_device_id da9052_ssc_id[] = {
+       { DA9052_SSC_I2C_DEVICE_NAME, 0},
+       {}
+};
+
+static struct i2c_driver da9052_i2c_driver =  {
+       .driver = {
+               .name   = DA9052_SSC_I2C_DEVICE_NAME,
+               .owner  = THIS_MODULE,
+       },
+       .probe  = da9052_i2c_probe,
+       .remove = da9052_i2c_remove,
+       .id_table       = da9052_ssc_id,
+};
+
+static int __init da9052_i2c_init(void)
+{
+       int ret = 0;
+       /* printk("\n\nEntered da9052_i2c_init................\n\n"); */
+       ret = i2c_add_driver(&da9052_i2c_driver);
+       if (ret != 0) {
+               printk(KERN_ERR "Unable to register %s\n",
+                      DA9052_SSC_I2C_DEVICE_NAME);
+               return ret;
+       }
+       return 0;
+}
+subsys_initcall(da9052_i2c_init);
+
+static void  __exit da9052_i2c_exit(void)
+{
+       i2c_del_driver(&da9052_i2c_driver);
+}
+module_exit(da9052_i2c_exit);
+
+MODULE_AUTHOR("Dialog Semiconductor Ltd <dc...@diasemi.com>");
+MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DA9052_SSC_I2C_DEVICE_NAME);
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
new file mode 100644
index 0000000..f25e188f
--- /dev/null
+++ b/drivers/mfd/da9052-spi.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright(c) 2009 Dialog Semiconductor Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * da9052-spi.c: SPI SSC (Synchronous Serial Communication) driver for DA9052
+ */
+
+#include <linux/device.h>
+#include <linux/mfd/core.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+
+struct da9052 *da9052_spi;
+
+#define SPI_CONNECTED 0
+
+static int da9052_spi_is_connected(void)
+{
+
+       struct da9052_ssc_msg msg;
+
+       /* printk("Entered da9052_spi_is_connected.............\n"); */
+
+       msg.addr = DA9052_INTERFACE_REG;
+
+       /* Test spi connectivity by performing read of the GPIO_0-1 register
+          and then verify the read value*/
+       if (0 != da9052_spi_read(da9052_spi, &msg)) {
+               printk(KERN_DEBUG "da9052_spi_is_connected - "\
+                      "spi read failed.............\n");
+               return -1;
+       } else if (0x88 != msg.data) {
+               printk(KERN_DEBUG "da9052_spi_is_connected - "          \
+                      "spi read failed. Msg data =%x ..............\n",
+                      msg.data);
+               return -1;
+       }
+
+       return 0;
+
+}
+
+static int da9052_spi_probe(struct spi_device *spi)
+{
+       /* printk("\n\tEntered da9052_spi_probe.....\n"); */
+
+       da9052_spi = kzalloc(sizeof(struct da9052), GFP_KERNEL);
+
+       if (!da9052_spi)
+               return -ENOMEM;
+
+
+       spi->mode = SPI_MODE_0 | SPI_CPOL;
+       spi->bits_per_word = 8;
+       spi_setup(spi);
+
+       da9052_spi->dev = &spi->dev;
+
+       da9052_spi->spi_dev = spi;
+
+       /*
+        * Allocate memory for RX/TX bufferes used in single register
+        * read/write
+        */
+       da9052_spi->spi_rx_buf = kmalloc(2, GFP_KERNEL | GFP_DMA);
+       if (!da9052_spi->spi_rx_buf)
+               return -ENOMEM;
+
+       da9052_spi->spi_tx_buf = kmalloc(2, GFP_KERNEL | GFP_DMA);
+       if (!da9052_spi->spi_tx_buf)
+               return -ENOMEM;
+
+       da9052_spi->spi_active_page  = PAGECON_0;
+       da9052_spi->rw_pol = 1;
+
+
+       dev_set_drvdata(&spi->dev, da9052_spi);
+
+
+       /* Validate SPI connectivity */
+       if (SPI_CONNECTED  == da9052_spi_is_connected()) {
+               /* SPI is connected */
+               da9052_spi->connecting_device = SPI;
+               if (0 != da9052_ssc_init(da9052_spi))
+                       return -ENODEV;
+       } else {
+               return -ENODEV;
+       }
+
+       /* printk("Exiting da9052_spi_probe.....\n"); */
+
+       return 0;
+}
+
+static int da9052_spi_remove(struct spi_device *spi)
+{
+       struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
+
+       printk("Entered da9052_spi_remove()\n");
+       if (SPI == da9052->connecting_device)
+               da9052_ssc_exit(da9052);
+       mfd_remove_devices(&spi->dev);
+       kfree(da9052->spi_rx_buf);
+       kfree(da9052->spi_tx_buf);
+       kfree(da9052);
+       return 0;
+}
+
+static struct spi_driver da9052_spi_driver = {
+       .driver = {
+               .name    = DA9052_SSC_SPI_DEVICE_NAME,
+               .bus    = &spi_bus_type,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = da9052_spi_probe,
+       .remove         = __devexit_p(da9052_spi_remove),
+};
+
+
+static int da9052_spi_set_page(struct da9052 *da9052, unsigned char page)
+{
+
+       struct da9052_ssc_msg sscmsg;
+       struct spi_message message;
+       struct spi_transfer xfer;
+       int ret = 0;
+
+       printk(KERN_DEBUG "Entered da9052_spi_set_page.....\n");
+       if ((page != PAGECON_0) && ((page != PAGECON_128)))
+               return INVALID_PAGE;
+
+       /* Current configuration is PAGE-0 and write request for PAGE-1 */
+       /* set register address */
+       sscmsg.addr = DA9052_PAGECON0_REG;
+       /* set value */
+       sscmsg.data = page;
+
+       /* Check value of R/W_POL bit of INTERFACE register */
+       if (!da9052->rw_pol) {
+               /* We need to set 0th bit for write operation */
+               sscmsg.addr = ((sscmsg.addr << 1) | RW_POL);
+       } else {
+               /* We need to reset 0th bit for write operation */
+               sscmsg.addr = (sscmsg.addr << 1);
+       }
+
+       /* SMDK-6410 host SPI driver specific stuff */
+
+       /* Build our spi message */
+       printk(KERN_DEBUG "da9052_spi_set_page - "\
+              "Calling spi_message_init.....\n");
+       spi_message_init(&message);
+       memset(&xfer, 0, sizeof(xfer));
+
+       xfer.len = 2;
+       xfer.tx_buf = da9052->spi_tx_buf;
+       xfer.rx_buf = da9052->spi_rx_buf;
+
+       da9052->spi_tx_buf[0] = sscmsg.addr;
+       da9052->spi_tx_buf[1] = sscmsg.data;
+
+       printk(KERN_DEBUG "da9052_spi_set_page - "\
+              "Calling spi_message_add_tail.....\n");
+       spi_message_add_tail(&xfer, &message);
+
+       /* Now, do the i/o */
+       printk(KERN_DEBUG "da9052_spi_set_page - Calling spi_sync.....\n");
+       ret = spi_sync(da9052->spi_dev, &message);
+
+       if (ret == 0) {
+               /* Active Page set successfully */
+               da9052->spi_active_page = page;
+               return 0;
+       } else {
+               /* Error in setting Active Page */
+               return ret;
+       }
+
+       return 0;
+}
+
+int da9052_spi_write(struct da9052 *da9052, struct da9052_ssc_msg *msg)
+{
+
+       struct spi_message message;
+       struct spi_transfer xfer;
+       int ret;
+
+       /*
+        * We need a seperate copy of da9052_ssc_msg so that caller's
+        * copy remains intact
+       */
+       struct da9052_ssc_msg sscmsg;
+
+       /* Copy callers data in to our local copy */
+       sscmsg.addr = msg->addr;
+       sscmsg.data = msg->data;
+
+       if ((sscmsg.addr > PAGE_0_END) &&
+               (da9052->spi_active_page == PAGECON_0)) {
+               /*
+               * Current configuration is PAGE-0 and write request
+               * for PAGE-1
+               */
+               da9052_spi_set_page(da9052, PAGECON_128);
+               /* Set register address accordindly */
+               sscmsg.addr = (sscmsg.addr - PAGE_1_START);
+       } else if ((sscmsg.addr < PAGE_1_START) &&
+               (da9052->spi_active_page == PAGECON_128)) {
+               /*
+               * Current configuration is PAGE-1 and write request
+               * for PAGE-0
+               */
+               da9052_spi_set_page(da9052, PAGECON_0);
+       } else if (sscmsg.addr > PAGE_0_END) {
+               /*
+               * Current configuration is PAGE-1 and write request
+               * for PAGE-1. Just need to adjust register address
+               */
+               sscmsg.addr = (sscmsg.addr - PAGE_1_START);
+       }
+
+       /* Check value of R/W_POL bit of INTERFACE register */
+       if (!da9052->rw_pol) {
+               /* We need to set 0th bit for write operation */
+               sscmsg.addr = ((sscmsg.addr << 1) | RW_POL);
+       } else {
+               /* We need to reset 0th bit for write operation */
+               sscmsg.addr = (sscmsg.addr << 1);
+       }
+
+       /* SMDK-6410 host SPI driver specific stuff */
+
+       /* Build our spi message */
+       spi_message_init(&message);
+       memset(&xfer, 0, sizeof(xfer));
+
+       xfer.len = 2;
+       xfer.tx_buf = da9052->spi_tx_buf;
+       xfer.rx_buf = da9052->spi_rx_buf;
+
+       da9052->spi_tx_buf[0] = sscmsg.addr;
+       da9052->spi_tx_buf[1] = sscmsg.data;
+
+       spi_message_add_tail(&xfer, &message);
+
+       /* Now, do the i/o */
+       ret = spi_sync(da9052->spi_dev, &message);
+
+       return ret;
+}
+
+int da9052_spi_write_many(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg,
+                         int msg_no)
+{
+       int cnt, ret = 0;
+
+       for (cnt = 0; cnt < msg_no; cnt++, sscmsg++) {
+               ret = da9052_ssc_write(da9052, sscmsg);
+               if (ret != 0) {
+                       printk(KERN_DEBUG "Error in %s\n", __func__);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+int da9052_spi_read(struct da9052 *da9052, struct da9052_ssc_msg *msg)
+{
+
+       struct spi_message message;
+       struct spi_transfer xfer;
+       int ret;
+
+       /*
+       * We need a seperate copy of da9052_ssc_msg so that
+       * caller's copy remains intact
+       */
+       struct da9052_ssc_msg sscmsg;
+
+
+       /* Copy callers data in to our local copy */
+       sscmsg.addr = msg->addr;
+       sscmsg.data = msg->data;
+
+       if ((sscmsg.addr > PAGE_0_END) &&
+               (da9052->spi_active_page == PAGECON_0)) {
+               /*
+               * Current configuration is PAGE-0 and
+               * read request for PAGE-1
+               */
+               printk(KERN_DEBUG "da9052_spi_read - if PAGECON_128.....\n");
+               da9052_spi_set_page(da9052, PAGECON_128);
+               /* Set register address accordindly */
+               sscmsg.addr = (sscmsg.addr - PAGE_1_START);
+       } else if ((sscmsg.addr < PAGE_1_START) &&
+               (da9052->spi_active_page == PAGECON_128)) {
+               /*
+               * Current configuration is PAGE-1 and
+               * write request for PAGE-0
+               */
+               printk(KERN_DEBUG "da9052_spi_read - if PAGECON_0.....\n");
+               da9052_spi_set_page(da9052, PAGECON_0);
+       } else if (sscmsg.addr > PAGE_0_END) {
+               /*
+               * Current configuration is PAGE-1 and write
+               * request for PAGE-1
+               * Just need to adjust register address
+               */
+               sscmsg.addr = (sscmsg.addr - PAGE_1_START);
+       }
+
+       /* Check value of R/W_POL bit of INTERFACE register */
+       if (da9052->rw_pol) {
+               /* We need to set 0th bit for read operation */
+               sscmsg.addr = ((sscmsg.addr << 1) | RW_POL);
+       } else {
+               /* We need to reset 0th bit for write operation */
+               sscmsg.addr = (sscmsg.addr << 1);
+       }
+
+       /* SMDK-6410 host SPI driver specific stuff */
+
+       /* Build our spi message */
+       spi_message_init(&message);
+       memset(&xfer, 0, sizeof(xfer));
+
+       xfer.len = 2;
+       xfer.tx_buf = da9052->spi_tx_buf;
+       xfer.rx_buf = da9052->spi_rx_buf;
+
+       da9052->spi_tx_buf[0] = sscmsg.addr;
+       da9052->spi_tx_buf[1] = 0xff;
+
+       da9052->spi_rx_buf[0] = 0;
+       da9052->spi_rx_buf[1] = 0;
+
+       spi_message_add_tail(&xfer, &message);
+
+       /* Now, do the i/o */
+       ret = spi_sync(da9052->spi_dev, &message);
+
+       if (ret == 0) {
+               /* Update read value in callers copy */
+               msg->data = da9052->spi_rx_buf[1];
+               return 0;
+       } else {
+               return ret;
+       }
+
+
+       return 0;
+}
+
+int da9052_spi_read_many(struct da9052 *da9052, struct da9052_ssc_msg *sscmsg,
+                        int msg_no)
+{
+       int cnt, ret = 0;
+
+       for (cnt = 0; cnt < msg_no; cnt++, sscmsg++) {
+               ret = da9052_ssc_read(da9052, sscmsg);
+               if (ret != 0) {
+                       printk(KERN_DEBUG "Error in %s\n", __func__);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int __init da9052_spi_init(void)
+{
+       int ret = 0;
+       /*printk("Entered da9052_spi_init.....\n");*/
+       ret = spi_register_driver(&da9052_spi_driver);
+       if (ret != 0) {
+               printk(KERN_ERR "Unable to register %s\n",
+                      DA9052_SSC_SPI_DEVICE_NAME);
+               return ret;
+       }
+       return 0;
+}
+module_init(da9052_spi_init);
+
+static void __exit da9052_spi_exit(void)
+{
+       spi_unregister_driver(&da9052_spi_driver);
+}
+
+module_exit(da9052_spi_exit);
+
+MODULE_AUTHOR("Dialog Semiconductor Ltd <dc...@diasemi.com>");
+MODULE_DESCRIPTION("SPI driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DA9052_SSC_SPI_DEVICE_NAME);
-- 
1.7.5.3


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to