#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/dln2.h>
#include <linux/spi/spi.h>
#include <linux/pm_runtime.h>
#include <asm/unaligned.h>
#define DLN2_SPI_MODULE_ID 0x02
#define DLN2_SPI_CMD(cmd) DLN2_CMD(cmd, DLN2_SPI_MODULE_ID)
#define DLN2_SPI_GET_PORT_COUNT DLN2_SPI_CMD(0x00)
#define DLN2_SPI_ENABLE DLN2_SPI_CMD(0x11)
#define DLN2_SPI_DISABLE DLN2_SPI_CMD(0x12)
#define DLN2_SPI_IS_ENABLED DLN2_SPI_CMD(0x13)
#define DLN2_SPI_SET_MODE DLN2_SPI_CMD(0x14)
#define DLN2_SPI_GET_MODE DLN2_SPI_CMD(0x15)
#define DLN2_SPI_SET_FRAME_SIZE DLN2_SPI_CMD(0x16)
#define DLN2_SPI_GET_FRAME_SIZE DLN2_SPI_CMD(0x17)
#define DLN2_SPI_SET_FREQUENCY DLN2_SPI_CMD(0x18)
#define DLN2_SPI_GET_FREQUENCY DLN2_SPI_CMD(0x19)
#define DLN2_SPI_READ_WRITE DLN2_SPI_CMD(0x1A)
#define DLN2_SPI_READ DLN2_SPI_CMD(0x1B)
#define DLN2_SPI_WRITE DLN2_SPI_CMD(0x1C)
#define DLN2_SPI_SET_DELAY_BETWEEN_SS DLN2_SPI_CMD(0x20)
#define DLN2_SPI_GET_DELAY_BETWEEN_SS DLN2_SPI_CMD(0x21)
#define DLN2_SPI_SET_DELAY_AFTER_SS DLN2_SPI_CMD(0x22)
#define DLN2_SPI_GET_DELAY_AFTER_SS DLN2_SPI_CMD(0x23)
#define DLN2_SPI_SET_DELAY_BETWEEN_FRAMES DLN2_SPI_CMD(0x24)
#define DLN2_SPI_GET_DELAY_BETWEEN_FRAMES DLN2_SPI_CMD(0x25)
#define DLN2_SPI_SET_SS DLN2_SPI_CMD(0x26)
#define DLN2_SPI_GET_SS DLN2_SPI_CMD(0x27)
#define DLN2_SPI_RELEASE_SS DLN2_SPI_CMD(0x28)
#define DLN2_SPI_SS_VARIABLE_ENABLE DLN2_SPI_CMD(0x2B)
#define DLN2_SPI_SS_VARIABLE_DISABLE DLN2_SPI_CMD(0x2C)
#define DLN2_SPI_SS_VARIABLE_IS_ENABLED DLN2_SPI_CMD(0x2D)
#define DLN2_SPI_SS_AAT_ENABLE DLN2_SPI_CMD(0x2E)
#define DLN2_SPI_SS_AAT_DISABLE DLN2_SPI_CMD(0x2F)
#define DLN2_SPI_SS_AAT_IS_ENABLED DLN2_SPI_CMD(0x30)
#define DLN2_SPI_SS_BETWEEN_FRAMES_ENABLE DLN2_SPI_CMD(0x31)
#define DLN2_SPI_SS_BETWEEN_FRAMES_DISABLE DLN2_SPI_CMD(0x32)
#define DLN2_SPI_SS_BETWEEN_FRAMES_IS_ENABLED DLN2_SPI_CMD(0x33)
#define DLN2_SPI_SET_CPHA DLN2_SPI_CMD(0x34)
#define DLN2_SPI_GET_CPHA DLN2_SPI_CMD(0x35)
#define DLN2_SPI_SET_CPOL DLN2_SPI_CMD(0x36)
#define DLN2_SPI_GET_CPOL DLN2_SPI_CMD(0x37)
#define DLN2_SPI_SS_MULTI_ENABLE DLN2_SPI_CMD(0x38)
#define DLN2_SPI_SS_MULTI_DISABLE DLN2_SPI_CMD(0x39)
#define DLN2_SPI_SS_MULTI_IS_ENABLED DLN2_SPI_CMD(0x3A)
#define DLN2_SPI_GET_SUPPORTED_MODES DLN2_SPI_CMD(0x40)
#define DLN2_SPI_GET_SUPPORTED_CPHA_VALUES DLN2_SPI_CMD(0x41)
#define DLN2_SPI_GET_SUPPORTED_CPOL_VALUES DLN2_SPI_CMD(0x42)
#define DLN2_SPI_GET_SUPPORTED_FRAME_SIZES DLN2_SPI_CMD(0x43)
#define DLN2_SPI_GET_SS_COUNT DLN2_SPI_CMD(0x44)
#define DLN2_SPI_GET_MIN_FREQUENCY DLN2_SPI_CMD(0x45)
#define DLN2_SPI_GET_MAX_FREQUENCY DLN2_SPI_CMD(0x46)
#define DLN2_SPI_GET_MIN_DELAY_BETWEEN_SS DLN2_SPI_CMD(0x47)
#define DLN2_SPI_GET_MAX_DELAY_BETWEEN_SS DLN2_SPI_CMD(0x48)
#define DLN2_SPI_GET_MIN_DELAY_AFTER_SS DLN2_SPI_CMD(0x49)
#define DLN2_SPI_GET_MAX_DELAY_AFTER_SS DLN2_SPI_CMD(0x4A)
#define DLN2_SPI_GET_MIN_DELAY_BETWEEN_FRAMES DLN2_SPI_CMD(0x4B)
#define DLN2_SPI_GET_MAX_DELAY_BETWEEN_FRAMES DLN2_SPI_CMD(0x4C)
#define DLN2_SPI_MAX_XFER_SIZE 256
#define DLN2_SPI_BUF_SIZE (DLN2_SPI_MAX_XFER_SIZE + 16)
#define DLN2_SPI_ATTR_LEAVE_SS_LOW BIT(0)
#define DLN2_TRANSFERS_WAIT_COMPLETE 1
#define DLN2_TRANSFERS_CANCEL 0
#define DLN2_RPM_AUTOSUSPEND_TIMEOUT 2000
struct dln2_spi {
struct platform_device *pdev;
struct spi_master *master;
u8 port;
void *buf;