17e2903cbSBaolin Wang /* 27e2903cbSBaolin Wang * Copyright (C) 2017 Spreadtrum Communications Inc. 37e2903cbSBaolin Wang * 47e2903cbSBaolin Wang * SPDX-License-Identifier: GPL-2.0 57e2903cbSBaolin Wang */ 67e2903cbSBaolin Wang 77e2903cbSBaolin Wang #include <linux/hwspinlock.h> 87e2903cbSBaolin Wang #include <linux/init.h> 97e2903cbSBaolin Wang #include <linux/io.h> 107e2903cbSBaolin Wang #include <linux/kernel.h> 117e2903cbSBaolin Wang #include <linux/module.h> 127e2903cbSBaolin Wang #include <linux/of.h> 137e2903cbSBaolin Wang #include <linux/of_device.h> 147e2903cbSBaolin Wang #include <linux/platform_device.h> 157e2903cbSBaolin Wang #include <linux/spi/spi.h> 167e2903cbSBaolin Wang #include <linux/sizes.h> 177e2903cbSBaolin Wang 187e2903cbSBaolin Wang /* Registers definitions for ADI controller */ 197e2903cbSBaolin Wang #define REG_ADI_CTRL0 0x4 207e2903cbSBaolin Wang #define REG_ADI_CHN_PRIL 0x8 217e2903cbSBaolin Wang #define REG_ADI_CHN_PRIH 0xc 227e2903cbSBaolin Wang #define REG_ADI_INT_EN 0x10 237e2903cbSBaolin Wang #define REG_ADI_INT_RAW 0x14 247e2903cbSBaolin Wang #define REG_ADI_INT_MASK 0x18 257e2903cbSBaolin Wang #define REG_ADI_INT_CLR 0x1c 267e2903cbSBaolin Wang #define REG_ADI_GSSI_CFG0 0x20 277e2903cbSBaolin Wang #define REG_ADI_GSSI_CFG1 0x24 287e2903cbSBaolin Wang #define REG_ADI_RD_CMD 0x28 297e2903cbSBaolin Wang #define REG_ADI_RD_DATA 0x2c 307e2903cbSBaolin Wang #define REG_ADI_ARM_FIFO_STS 0x30 317e2903cbSBaolin Wang #define REG_ADI_STS 0x34 327e2903cbSBaolin Wang #define REG_ADI_EVT_FIFO_STS 0x38 337e2903cbSBaolin Wang #define REG_ADI_ARM_CMD_STS 0x3c 347e2903cbSBaolin Wang #define REG_ADI_CHN_EN 0x40 357e2903cbSBaolin Wang #define REG_ADI_CHN_ADDR(id) (0x44 + (id - 2) * 4) 367e2903cbSBaolin Wang #define REG_ADI_CHN_EN1 0x20c 377e2903cbSBaolin Wang 387e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_GSSI_CFG0 */ 397e2903cbSBaolin Wang #define BIT_CLK_ALL_ON BIT(30) 407e2903cbSBaolin Wang 417e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_RD_DATA */ 427e2903cbSBaolin Wang #define BIT_RD_CMD_BUSY BIT(31) 437e2903cbSBaolin Wang #define RD_ADDR_SHIFT 16 447e2903cbSBaolin Wang #define RD_VALUE_MASK GENMASK(15, 0) 457e2903cbSBaolin Wang #define RD_ADDR_MASK GENMASK(30, 16) 467e2903cbSBaolin Wang 477e2903cbSBaolin Wang /* Bits definitions for register REG_ADI_ARM_FIFO_STS */ 487e2903cbSBaolin Wang #define BIT_FIFO_FULL BIT(11) 497e2903cbSBaolin Wang #define BIT_FIFO_EMPTY BIT(10) 507e2903cbSBaolin Wang 517e2903cbSBaolin Wang /* 527e2903cbSBaolin Wang * ADI slave devices include RTC, ADC, regulator, charger, thermal and so on. 537e2903cbSBaolin Wang * The slave devices address offset is always 0x8000 and size is 4K. 547e2903cbSBaolin Wang */ 557e2903cbSBaolin Wang #define ADI_SLAVE_ADDR_SIZE SZ_4K 567e2903cbSBaolin Wang #define ADI_SLAVE_OFFSET 0x8000 577e2903cbSBaolin Wang 587e2903cbSBaolin Wang /* Timeout (ms) for the trylock of hardware spinlocks */ 597e2903cbSBaolin Wang #define ADI_HWSPINLOCK_TIMEOUT 5000 607e2903cbSBaolin Wang /* 617e2903cbSBaolin Wang * ADI controller has 50 channels including 2 software channels 627e2903cbSBaolin Wang * and 48 hardware channels. 637e2903cbSBaolin Wang */ 647e2903cbSBaolin Wang #define ADI_HW_CHNS 50 657e2903cbSBaolin Wang 667e2903cbSBaolin Wang #define ADI_FIFO_DRAIN_TIMEOUT 1000 677e2903cbSBaolin Wang #define ADI_READ_TIMEOUT 2000 687e2903cbSBaolin Wang #define REG_ADDR_LOW_MASK GENMASK(11, 0) 697e2903cbSBaolin Wang 707e2903cbSBaolin Wang struct sprd_adi { 717e2903cbSBaolin Wang struct spi_controller *ctlr; 727e2903cbSBaolin Wang struct device *dev; 737e2903cbSBaolin Wang void __iomem *base; 747e2903cbSBaolin Wang struct hwspinlock *hwlock; 757e2903cbSBaolin Wang unsigned long slave_vbase; 767e2903cbSBaolin Wang unsigned long slave_pbase; 777e2903cbSBaolin Wang }; 787e2903cbSBaolin Wang 797e2903cbSBaolin Wang static int sprd_adi_check_paddr(struct sprd_adi *sadi, u32 paddr) 807e2903cbSBaolin Wang { 817e2903cbSBaolin Wang if (paddr < sadi->slave_pbase || paddr > 827e2903cbSBaolin Wang (sadi->slave_pbase + ADI_SLAVE_ADDR_SIZE)) { 837e2903cbSBaolin Wang dev_err(sadi->dev, 847e2903cbSBaolin Wang "slave physical address is incorrect, addr = 0x%x\n", 857e2903cbSBaolin Wang paddr); 867e2903cbSBaolin Wang return -EINVAL; 877e2903cbSBaolin Wang } 887e2903cbSBaolin Wang 897e2903cbSBaolin Wang return 0; 907e2903cbSBaolin Wang } 917e2903cbSBaolin Wang 927e2903cbSBaolin Wang static unsigned long sprd_adi_to_vaddr(struct sprd_adi *sadi, u32 paddr) 937e2903cbSBaolin Wang { 947e2903cbSBaolin Wang return (paddr - sadi->slave_pbase + sadi->slave_vbase); 957e2903cbSBaolin Wang } 967e2903cbSBaolin Wang 977e2903cbSBaolin Wang static int sprd_adi_drain_fifo(struct sprd_adi *sadi) 987e2903cbSBaolin Wang { 997e2903cbSBaolin Wang u32 timeout = ADI_FIFO_DRAIN_TIMEOUT; 1007e2903cbSBaolin Wang u32 sts; 1017e2903cbSBaolin Wang 1027e2903cbSBaolin Wang do { 1037e2903cbSBaolin Wang sts = readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS); 1047e2903cbSBaolin Wang if (sts & BIT_FIFO_EMPTY) 1057e2903cbSBaolin Wang break; 1067e2903cbSBaolin Wang 1077e2903cbSBaolin Wang cpu_relax(); 1087e2903cbSBaolin Wang } while (--timeout); 1097e2903cbSBaolin Wang 1107e2903cbSBaolin Wang if (timeout == 0) { 1117e2903cbSBaolin Wang dev_err(sadi->dev, "drain write fifo timeout\n"); 1127e2903cbSBaolin Wang return -EBUSY; 1137e2903cbSBaolin Wang } 1147e2903cbSBaolin Wang 1157e2903cbSBaolin Wang return 0; 1167e2903cbSBaolin Wang } 1177e2903cbSBaolin Wang 1187e2903cbSBaolin Wang static int sprd_adi_fifo_is_full(struct sprd_adi *sadi) 1197e2903cbSBaolin Wang { 1207e2903cbSBaolin Wang return readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS) & BIT_FIFO_FULL; 1217e2903cbSBaolin Wang } 1227e2903cbSBaolin Wang 1237e2903cbSBaolin Wang static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val) 1247e2903cbSBaolin Wang { 1257e2903cbSBaolin Wang int read_timeout = ADI_READ_TIMEOUT; 1267e2903cbSBaolin Wang u32 val, rd_addr; 1277e2903cbSBaolin Wang 1287e2903cbSBaolin Wang /* 1297e2903cbSBaolin Wang * Set the physical register address need to read into RD_CMD register, 1307e2903cbSBaolin Wang * then ADI controller will start to transfer automatically. 1317e2903cbSBaolin Wang */ 1327e2903cbSBaolin Wang writel_relaxed(reg_paddr, sadi->base + REG_ADI_RD_CMD); 1337e2903cbSBaolin Wang 1347e2903cbSBaolin Wang /* 1357e2903cbSBaolin Wang * Wait read operation complete, the BIT_RD_CMD_BUSY will be set 1367e2903cbSBaolin Wang * simultaneously when writing read command to register, and the 1377e2903cbSBaolin Wang * BIT_RD_CMD_BUSY will be cleared after the read operation is 1387e2903cbSBaolin Wang * completed. 1397e2903cbSBaolin Wang */ 1407e2903cbSBaolin Wang do { 1417e2903cbSBaolin Wang val = readl_relaxed(sadi->base + REG_ADI_RD_DATA); 1427e2903cbSBaolin Wang if (!(val & BIT_RD_CMD_BUSY)) 1437e2903cbSBaolin Wang break; 1447e2903cbSBaolin Wang 1457e2903cbSBaolin Wang cpu_relax(); 1467e2903cbSBaolin Wang } while (--read_timeout); 1477e2903cbSBaolin Wang 1487e2903cbSBaolin Wang if (read_timeout == 0) { 1497e2903cbSBaolin Wang dev_err(sadi->dev, "ADI read timeout\n"); 1507e2903cbSBaolin Wang return -EBUSY; 1517e2903cbSBaolin Wang } 1527e2903cbSBaolin Wang 1537e2903cbSBaolin Wang /* 1547e2903cbSBaolin Wang * The return value includes data and read register address, from bit 0 1557e2903cbSBaolin Wang * to bit 15 are data, and from bit 16 to bit 30 are read register 1567e2903cbSBaolin Wang * address. Then we can check the returned register address to validate 1577e2903cbSBaolin Wang * data. 1587e2903cbSBaolin Wang */ 1597e2903cbSBaolin Wang rd_addr = (val & RD_ADDR_MASK ) >> RD_ADDR_SHIFT; 1607e2903cbSBaolin Wang 1617e2903cbSBaolin Wang if (rd_addr != (reg_paddr & REG_ADDR_LOW_MASK)) { 1627e2903cbSBaolin Wang dev_err(sadi->dev, "read error, reg addr = 0x%x, val = 0x%x\n", 1637e2903cbSBaolin Wang reg_paddr, val); 1647e2903cbSBaolin Wang return -EIO; 1657e2903cbSBaolin Wang } 1667e2903cbSBaolin Wang 1677e2903cbSBaolin Wang *read_val = val & RD_VALUE_MASK; 1687e2903cbSBaolin Wang return 0; 1697e2903cbSBaolin Wang } 1707e2903cbSBaolin Wang 1717e2903cbSBaolin Wang static int sprd_adi_write(struct sprd_adi *sadi, unsigned long reg, u32 val) 1727e2903cbSBaolin Wang { 1737e2903cbSBaolin Wang u32 timeout = ADI_FIFO_DRAIN_TIMEOUT; 1747e2903cbSBaolin Wang int ret; 1757e2903cbSBaolin Wang 1767e2903cbSBaolin Wang ret = sprd_adi_drain_fifo(sadi); 1777e2903cbSBaolin Wang if (ret < 0) 1787e2903cbSBaolin Wang return ret; 1797e2903cbSBaolin Wang 1807e2903cbSBaolin Wang /* 1817e2903cbSBaolin Wang * we should wait for write fifo is empty before writing data to PMIC 1827e2903cbSBaolin Wang * registers. 1837e2903cbSBaolin Wang */ 1847e2903cbSBaolin Wang do { 1857e2903cbSBaolin Wang if (!sprd_adi_fifo_is_full(sadi)) { 1867e2903cbSBaolin Wang writel_relaxed(val, (void __iomem *)reg); 1877e2903cbSBaolin Wang break; 1887e2903cbSBaolin Wang } 1897e2903cbSBaolin Wang 1907e2903cbSBaolin Wang cpu_relax(); 1917e2903cbSBaolin Wang } while (--timeout); 1927e2903cbSBaolin Wang 1937e2903cbSBaolin Wang if (timeout == 0) { 1947e2903cbSBaolin Wang dev_err(sadi->dev, "write fifo is full\n"); 1957e2903cbSBaolin Wang return -EBUSY; 1967e2903cbSBaolin Wang } 1977e2903cbSBaolin Wang 1987e2903cbSBaolin Wang return 0; 1997e2903cbSBaolin Wang } 2007e2903cbSBaolin Wang 2017e2903cbSBaolin Wang static int sprd_adi_transfer_one(struct spi_controller *ctlr, 2027e2903cbSBaolin Wang struct spi_device *spi_dev, 2037e2903cbSBaolin Wang struct spi_transfer *t) 2047e2903cbSBaolin Wang { 2057e2903cbSBaolin Wang struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); 2067e2903cbSBaolin Wang unsigned long flags, virt_reg; 2077e2903cbSBaolin Wang u32 phy_reg, val; 2087e2903cbSBaolin Wang int ret; 2097e2903cbSBaolin Wang 2107e2903cbSBaolin Wang if (t->rx_buf) { 2117e2903cbSBaolin Wang phy_reg = *(u32 *)t->rx_buf + sadi->slave_pbase; 2127e2903cbSBaolin Wang 2137e2903cbSBaolin Wang ret = sprd_adi_check_paddr(sadi, phy_reg); 2147e2903cbSBaolin Wang if (ret) 2157e2903cbSBaolin Wang return ret; 2167e2903cbSBaolin Wang 2177e2903cbSBaolin Wang ret = hwspin_lock_timeout_irqsave(sadi->hwlock, 2187e2903cbSBaolin Wang ADI_HWSPINLOCK_TIMEOUT, 2197e2903cbSBaolin Wang &flags); 2207e2903cbSBaolin Wang if (ret) { 2217e2903cbSBaolin Wang dev_err(sadi->dev, "get the hw lock failed\n"); 2227e2903cbSBaolin Wang return ret; 2237e2903cbSBaolin Wang } 2247e2903cbSBaolin Wang 2257e2903cbSBaolin Wang ret = sprd_adi_read(sadi, phy_reg, &val); 2267e2903cbSBaolin Wang hwspin_unlock_irqrestore(sadi->hwlock, &flags); 2277e2903cbSBaolin Wang if (ret) 2287e2903cbSBaolin Wang return ret; 2297e2903cbSBaolin Wang 2307e2903cbSBaolin Wang *(u32 *)t->rx_buf = val; 2317e2903cbSBaolin Wang } else if (t->tx_buf) { 2327e2903cbSBaolin Wang u32 *p = (u32 *)t->tx_buf; 2337e2903cbSBaolin Wang 2347e2903cbSBaolin Wang /* 2357e2903cbSBaolin Wang * Get the physical register address need to write and convert 2367e2903cbSBaolin Wang * the physical address to virtual address. Since we need 2377e2903cbSBaolin Wang * virtual register address to write. 2387e2903cbSBaolin Wang */ 2397e2903cbSBaolin Wang phy_reg = *p++ + sadi->slave_pbase; 2407e2903cbSBaolin Wang ret = sprd_adi_check_paddr(sadi, phy_reg); 2417e2903cbSBaolin Wang if (ret) 2427e2903cbSBaolin Wang return ret; 2437e2903cbSBaolin Wang 2447e2903cbSBaolin Wang virt_reg = sprd_adi_to_vaddr(sadi, phy_reg); 2457e2903cbSBaolin Wang val = *p; 2467e2903cbSBaolin Wang 2477e2903cbSBaolin Wang ret = hwspin_lock_timeout_irqsave(sadi->hwlock, 2487e2903cbSBaolin Wang ADI_HWSPINLOCK_TIMEOUT, 2497e2903cbSBaolin Wang &flags); 2507e2903cbSBaolin Wang if (ret) { 2517e2903cbSBaolin Wang dev_err(sadi->dev, "get the hw lock failed\n"); 2527e2903cbSBaolin Wang return ret; 2537e2903cbSBaolin Wang } 2547e2903cbSBaolin Wang 2557e2903cbSBaolin Wang ret = sprd_adi_write(sadi, virt_reg, val); 2567e2903cbSBaolin Wang hwspin_unlock_irqrestore(sadi->hwlock, &flags); 2577e2903cbSBaolin Wang if (ret) 2587e2903cbSBaolin Wang return ret; 2597e2903cbSBaolin Wang } else { 2607e2903cbSBaolin Wang dev_err(sadi->dev, "no buffer for transfer\n"); 2617e2903cbSBaolin Wang return -EINVAL; 2627e2903cbSBaolin Wang } 2637e2903cbSBaolin Wang 2647e2903cbSBaolin Wang return 0; 2657e2903cbSBaolin Wang } 2667e2903cbSBaolin Wang 2677e2903cbSBaolin Wang static void sprd_adi_hw_init(struct sprd_adi *sadi) 2687e2903cbSBaolin Wang { 2697e2903cbSBaolin Wang struct device_node *np = sadi->dev->of_node; 2707e2903cbSBaolin Wang int i, size, chn_cnt; 2717e2903cbSBaolin Wang const __be32 *list; 2727e2903cbSBaolin Wang u32 tmp; 2737e2903cbSBaolin Wang 2747e2903cbSBaolin Wang /* Address bits select default 12 bits */ 2757e2903cbSBaolin Wang writel_relaxed(0, sadi->base + REG_ADI_CTRL0); 2767e2903cbSBaolin Wang 2777e2903cbSBaolin Wang /* Set all channels as default priority */ 2787e2903cbSBaolin Wang writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL); 2797e2903cbSBaolin Wang writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIH); 2807e2903cbSBaolin Wang 2817e2903cbSBaolin Wang /* Set clock auto gate mode */ 2827e2903cbSBaolin Wang tmp = readl_relaxed(sadi->base + REG_ADI_GSSI_CFG0); 2837e2903cbSBaolin Wang tmp &= ~BIT_CLK_ALL_ON; 2847e2903cbSBaolin Wang writel_relaxed(tmp, sadi->base + REG_ADI_GSSI_CFG0); 2857e2903cbSBaolin Wang 2867e2903cbSBaolin Wang /* Set hardware channels setting */ 2877e2903cbSBaolin Wang list = of_get_property(np, "sprd,hw-channels", &size); 2887e2903cbSBaolin Wang if (!size || !list) { 2897e2903cbSBaolin Wang dev_info(sadi->dev, "no hw channels setting in node\n"); 2907e2903cbSBaolin Wang return; 2917e2903cbSBaolin Wang } 2927e2903cbSBaolin Wang 2937e2903cbSBaolin Wang chn_cnt = size / 8; 2947e2903cbSBaolin Wang for (i = 0; i < chn_cnt; i++) { 2957e2903cbSBaolin Wang u32 value; 2967e2903cbSBaolin Wang u32 chn_id = be32_to_cpu(*list++); 2977e2903cbSBaolin Wang u32 chn_config = be32_to_cpu(*list++); 2987e2903cbSBaolin Wang 2997e2903cbSBaolin Wang /* Channel 0 and 1 are software channels */ 3007e2903cbSBaolin Wang if (chn_id < 2) 3017e2903cbSBaolin Wang continue; 3027e2903cbSBaolin Wang 3037e2903cbSBaolin Wang writel_relaxed(chn_config, sadi->base + 3047e2903cbSBaolin Wang REG_ADI_CHN_ADDR(chn_id)); 3057e2903cbSBaolin Wang 3067e2903cbSBaolin Wang if (chn_id < 31) { 3077e2903cbSBaolin Wang value = readl_relaxed(sadi->base + REG_ADI_CHN_EN); 3087e2903cbSBaolin Wang value |= BIT(chn_id); 3097e2903cbSBaolin Wang writel_relaxed(value, sadi->base + REG_ADI_CHN_EN); 3107e2903cbSBaolin Wang } else if (chn_id < ADI_HW_CHNS) { 3117e2903cbSBaolin Wang value = readl_relaxed(sadi->base + REG_ADI_CHN_EN1); 3127e2903cbSBaolin Wang value |= BIT(chn_id - 32); 3137e2903cbSBaolin Wang writel_relaxed(value, sadi->base + REG_ADI_CHN_EN1); 3147e2903cbSBaolin Wang } 3157e2903cbSBaolin Wang } 3167e2903cbSBaolin Wang } 3177e2903cbSBaolin Wang 3187e2903cbSBaolin Wang static int sprd_adi_probe(struct platform_device *pdev) 3197e2903cbSBaolin Wang { 3207e2903cbSBaolin Wang struct device_node *np = pdev->dev.of_node; 3217e2903cbSBaolin Wang struct spi_controller *ctlr; 3227e2903cbSBaolin Wang struct sprd_adi *sadi; 3237e2903cbSBaolin Wang struct resource *res; 3247e2903cbSBaolin Wang u32 num_chipselect; 3257e2903cbSBaolin Wang int ret; 3267e2903cbSBaolin Wang 3277e2903cbSBaolin Wang if (!np) { 3287e2903cbSBaolin Wang dev_err(&pdev->dev, "can not find the adi bus node\n"); 3297e2903cbSBaolin Wang return -ENODEV; 3307e2903cbSBaolin Wang } 3317e2903cbSBaolin Wang 3327e2903cbSBaolin Wang pdev->id = of_alias_get_id(np, "spi"); 3337e2903cbSBaolin Wang num_chipselect = of_get_child_count(np); 3347e2903cbSBaolin Wang 3357e2903cbSBaolin Wang ctlr = spi_alloc_master(&pdev->dev, sizeof(struct sprd_adi)); 3367e2903cbSBaolin Wang if (!ctlr) 3377e2903cbSBaolin Wang return -ENOMEM; 3387e2903cbSBaolin Wang 3397e2903cbSBaolin Wang dev_set_drvdata(&pdev->dev, ctlr); 3407e2903cbSBaolin Wang sadi = spi_controller_get_devdata(ctlr); 3417e2903cbSBaolin Wang 3427e2903cbSBaolin Wang res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 3437e2903cbSBaolin Wang sadi->base = devm_ioremap_resource(&pdev->dev, res); 3447e2903cbSBaolin Wang if (!sadi->base) { 3457e2903cbSBaolin Wang ret = -ENOMEM; 3467e2903cbSBaolin Wang goto put_ctlr; 3477e2903cbSBaolin Wang } 3487e2903cbSBaolin Wang 3497e2903cbSBaolin Wang sadi->slave_vbase = (unsigned long)sadi->base + ADI_SLAVE_OFFSET; 3507e2903cbSBaolin Wang sadi->slave_pbase = res->start + ADI_SLAVE_OFFSET; 3517e2903cbSBaolin Wang sadi->ctlr = ctlr; 3527e2903cbSBaolin Wang sadi->dev = &pdev->dev; 3537e2903cbSBaolin Wang ret = of_hwspin_lock_get_id(np, 0); 3547e2903cbSBaolin Wang if (ret < 0) { 3557e2903cbSBaolin Wang dev_err(&pdev->dev, "can not get the hardware spinlock\n"); 3567e2903cbSBaolin Wang goto put_ctlr; 3577e2903cbSBaolin Wang } 3587e2903cbSBaolin Wang 3597e2903cbSBaolin Wang sadi->hwlock = hwspin_lock_request_specific(ret); 3607e2903cbSBaolin Wang if (!sadi->hwlock) { 3617e2903cbSBaolin Wang ret = -ENXIO; 3627e2903cbSBaolin Wang goto put_ctlr; 3637e2903cbSBaolin Wang } 3647e2903cbSBaolin Wang 3657e2903cbSBaolin Wang sprd_adi_hw_init(sadi); 3667e2903cbSBaolin Wang 3677e2903cbSBaolin Wang ctlr->dev.of_node = pdev->dev.of_node; 3687e2903cbSBaolin Wang ctlr->bus_num = pdev->id; 3697e2903cbSBaolin Wang ctlr->num_chipselect = num_chipselect; 3707e2903cbSBaolin Wang ctlr->flags = SPI_MASTER_HALF_DUPLEX; 3717e2903cbSBaolin Wang ctlr->bits_per_word_mask = 0; 3727e2903cbSBaolin Wang ctlr->transfer_one = sprd_adi_transfer_one; 3737e2903cbSBaolin Wang 3747e2903cbSBaolin Wang ret = devm_spi_register_controller(&pdev->dev, ctlr); 3757e2903cbSBaolin Wang if (ret) { 3767e2903cbSBaolin Wang dev_err(&pdev->dev, "failed to register SPI controller\n"); 3777e2903cbSBaolin Wang goto free_hwlock; 3787e2903cbSBaolin Wang } 3797e2903cbSBaolin Wang 3807e2903cbSBaolin Wang return 0; 3817e2903cbSBaolin Wang 3827e2903cbSBaolin Wang free_hwlock: 3837e2903cbSBaolin Wang hwspin_lock_free(sadi->hwlock); 3847e2903cbSBaolin Wang put_ctlr: 3857e2903cbSBaolin Wang spi_controller_put(ctlr); 3867e2903cbSBaolin Wang return ret; 3877e2903cbSBaolin Wang } 3887e2903cbSBaolin Wang 3897e2903cbSBaolin Wang static int sprd_adi_remove(struct platform_device *pdev) 3907e2903cbSBaolin Wang { 3917e2903cbSBaolin Wang struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev); 3927e2903cbSBaolin Wang struct sprd_adi *sadi = spi_controller_get_devdata(ctlr); 3937e2903cbSBaolin Wang 3947e2903cbSBaolin Wang hwspin_lock_free(sadi->hwlock); 3957e2903cbSBaolin Wang return 0; 3967e2903cbSBaolin Wang } 3977e2903cbSBaolin Wang 3987e2903cbSBaolin Wang static const struct of_device_id sprd_adi_of_match[] = { 3997e2903cbSBaolin Wang { 4007e2903cbSBaolin Wang .compatible = "sprd,sc9860-adi", 4017e2903cbSBaolin Wang }, 4027e2903cbSBaolin Wang { }, 4037e2903cbSBaolin Wang }; 4047e2903cbSBaolin Wang MODULE_DEVICE_TABLE(of, sprd_adi_of_match); 4057e2903cbSBaolin Wang 4067e2903cbSBaolin Wang static struct platform_driver sprd_adi_driver = { 4077e2903cbSBaolin Wang .driver = { 4087e2903cbSBaolin Wang .name = "sprd-adi", 4097e2903cbSBaolin Wang .owner = THIS_MODULE, 4107e2903cbSBaolin Wang .of_match_table = sprd_adi_of_match, 4117e2903cbSBaolin Wang }, 4127e2903cbSBaolin Wang .probe = sprd_adi_probe, 4137e2903cbSBaolin Wang .remove = sprd_adi_remove, 4147e2903cbSBaolin Wang }; 4157e2903cbSBaolin Wang module_platform_driver(sprd_adi_driver); 4167e2903cbSBaolin Wang 4177e2903cbSBaolin Wang MODULE_DESCRIPTION("Spreadtrum ADI Controller Driver"); 4187e2903cbSBaolin Wang MODULE_AUTHOR("Baolin Wang <Baolin.Wang@spreadtrum.com>"); 4197e2903cbSBaolin Wang MODULE_LICENSE("GPL v2"); 420