static int mx31_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << MX31_CSPICTRL_DR_SHIFT; if (cpu_is_mx31()) reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; else if (cpu_is_mx25() || cpu_is_mx35()) { reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; reg |= MX31_CSPICTRL_SSCTL; } if (config->mode & SPI_CPHA) reg |= MX31_CSPICTRL_PHA; if (config->mode & SPI_CPOL) reg |= MX31_CSPICTRL_POL; if (config->mode & SPI_CS_HIGH) reg |= MX31_CSPICTRL_SSPOL; if (config->cs < 0) { if (cpu_is_mx31()) reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; else if (cpu_is_mx25() || cpu_is_mx35()) reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; } writel(reg, spi_imx->base + MXC_CSPICTRL); return 0; }
static int __init mx3_devices_init(void) { if (cpu_is_mx31()) { mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR; imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff; mxc_register_device(&mxc_rnga_device, NULL); } if (cpu_is_mx35()) { mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0x1fff; otg_resources[0].start = MX35_OTG_BASE_ADDR; otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff; otg_resources[1].start = MXC_INT_USBOTG; otg_resources[1].end = MXC_INT_USBOTG; mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400; mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff; mxc_usbh1_resources[1].start = MXC_INT_USBHS; mxc_usbh1_resources[1].end = MXC_INT_USBHS; imx_ssi_resources0[1].start = MX35_INT_SSI1; imx_ssi_resources0[1].end = MX35_INT_SSI1; imx_ssi_resources1[1].start = MX35_INT_SSI2; imx_ssi_resources1[1].end = MX35_INT_SSI2; imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; } return 0; }
void pmic_voltage_init(void) { t_regulator_voltage volt; /* Enable 4 mc13783 output voltages */ pmic_write_reg(REG_ARBITRATION_SWITCHERS, (1 << 5), (1 << 5)); /* Set mc13783 DVS speed 25mV each 4us */ pmic_write_reg(REG_SWITCHERS_4, (0 << 6), (3 << 6)); if (cpu_is_mx31()) volt.sw1a = SW1A_1_625V; else volt.sw1a = SW1A_1_425V; pmic_power_regulator_set_voltage(SW_SW1A, volt); volt.sw1a = SW1A_1_25V; pmic_power_switcher_set_dvs(SW_SW1A, volt); if (cpu_is_mx32()) { volt.sw1a = SW1A_0_975V; pmic_power_switcher_set_stby(SW_SW1A, volt); } volt.sw1b = SW1A_1_25V; pmic_power_switcher_set_dvs(SW_SW1B, volt); volt.sw1b = SW1A_1_25V; pmic_power_switcher_set_stby(SW_SW1B, volt); }
static void mxc_init_nand_mtd(void) { if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) { mxc_nand_data.width = 2; } if (cpu_is_mx31()) { (void)platform_device_register(&mxc_nand_mtd_device); } if (cpu_is_mx32()) { (void)platform_device_register(&mxc_nandv2_mtd_device); } }
int mxc_set_usbcontrol(int port, unsigned int flags) { unsigned int v; if (cpu_is_mx31()) { v = readl(IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; if (flags & MXC_EHCI_POWER_PINS_ENABLED) v |= MX31_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; if (flags & MXC_EHCI_POWER_PINS_ENABLED) v |= MX31_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H1_DT_BIT; break; case 2: /* H2 port */ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H2_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H2_DT_BIT; break; } writel(v, IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } printk(KERN_WARNING "%s() unable to setup USBCONTROL for this CPU\n", __func__); return -EINVAL; }
static int post_cpu_init(void) { #ifdef CONFIG_MACH_MX27 if (cpu_is_mx27()) ipipe_mach_allow_hwtimer_uaccess(MX27_IO_P2V(MX27_AIPI_BASE_ADDR), 3); #endif /* CONFIG_MACH_MX27 */ #ifdef CONFIG_MACH_MX25 if (cpu_is_mx25()) ipipe_mach_allow_hwtimer_uaccess(MX25_AIPS1_BASE_ADDR_VIRT, MX25_AIPS2_BASE_ADDR_VIRT); #endif /* CONFIG_MACH_MX25 */ #ifdef CONFIG_MACH_MX31 if (cpu_is_mx31()) ipipe_mach_allow_hwtimer_uaccess(AIPS1_BASE_ADDR_VIRT, AIPS2_BASE_ADDR_VIRT); #endif /* CONFIG_MACH_MX31 */ return 0; }
static int mxc_audmux_v2_init(void) { int ret; if (cpu_is_mx35()) { audmux_clk = clk_get(NULL, "audmux"); if (IS_ERR(audmux_clk)) { ret = PTR_ERR(audmux_clk); printk(KERN_ERR "%s: cannot get clock: %d\n", __func__, ret); return ret; } } if (cpu_is_mx31() || cpu_is_mx35()) audmux_base = IO_ADDRESS(AUDMUX_BASE_ADDR); return 0; }
static int mxc_init_l2x0(void) { void __iomem *l2x0_base; void __iomem *clkctl_base; if (!cpu_is_mx31() && !cpu_is_mx35()) return 0; /* * First of all, we must repair broken chip settings. There are some * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These * misconfigured CPUs will run amok immediately when the L2 cache gets enabled. * Workaraound is to setup the correct register setting prior enabling the * L2 cache. This should not hurt already working CPUs, as they are using the * same value. */ #define L2_MEM_VAL 0x10 clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096); if (clkctl_base != NULL) { writel(0x00000515, clkctl_base + L2_MEM_VAL); iounmap(clkctl_base); } else { pr_err("L2 cache: Cannot fix timing. Trying to continue without\n"); } l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096); if (IS_ERR(l2x0_base)) { printk(KERN_ERR "remapping L2 cache area failed with %ld\n", PTR_ERR(l2x0_base)); return 0; } l2x0_init(l2x0_base, 0x00030024, 0x00000000); return 0; }
int mxc_initialize_usb_hw(int port, unsigned int flags) { unsigned int v; #if defined(CONFIG_ARCH_MX25) if (cpu_is_mx25()) { v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX35_H1_TLL_BIT; if (flags & MXC_EHCI_INTERNAL_PHY) v |= MX35_H1_USBTE_BIT; if (flags & MXC_EHCI_IPPUE_DOWN) v |= MX35_H1_IPPUE_DOWN_BIT; if (flags & MXC_EHCI_IPPUE_UP) v |= MX35_H1_IPPUE_UP_BIT; break; default: return -EINVAL; } writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_ARCH_MX25 */ #if defined(CONFIG_ARCH_MX3) if (cpu_is_mx31()) { v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H1_DT_BIT; break; case 2: /* H2 port */ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H2_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H2_DT_BIT; break; default: return -EINVAL; } writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } if (cpu_is_mx35()) { v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX35_H1_TLL_BIT; if (flags & MXC_EHCI_INTERNAL_PHY) v |= MX35_H1_USBTE_BIT; if (flags & MXC_EHCI_IPPUE_DOWN) v |= MX35_H1_IPPUE_DOWN_BIT; if (flags & MXC_EHCI_IPPUE_UP) v |= MX35_H1_IPPUE_UP_BIT; break; default: return -EINVAL; } writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_ARCH_MX3 */ #ifdef CONFIG_MACH_MX27 if (cpu_is_mx27()) { /* On i.MX27 we can use the i.MX31 USBCTRL bits, they * are identical */ v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H1_DT_BIT; break; case 2: /* H2 port */ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H2_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H2_DT_BIT; break; default: return -EINVAL; } writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_MACH_MX27 */ #ifdef CONFIG_ARCH_MX51 if (cpu_is_mx51()) { void __iomem *usb_base; u32 usbotg_base; u32 usbother_base; int ret = 0; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); switch (port) { case 0: /* OTG port */ usbotg_base = usb_base + MXC_OTG_OFFSET; break; case 1: /* Host 1 port */ usbotg_base = usb_base + MXC_H1_OFFSET; break; default: printk(KERN_ERR"%s no such port %d\n", __func__, port); ret = -ENOENT; goto error; } usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; switch (port) { case 0: /*OTG port */ if (flags & MXC_EHCI_INTERNAL_PHY) { v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); if (flags & MXC_EHCI_POWER_PINS_ENABLED) v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */ else v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); if (flags & MXC_EHCI_WAKEUP_ENABLED) v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */ else v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); } break; case 1: /* Host 1 */ /*Host ULPI */ v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); if (flags & MXC_EHCI_WAKEUP_ENABLED) v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ else v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ if (flags & MXC_EHCI_POWER_PINS_ENABLED) v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ else v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); if (flags & MXC_EHCI_POWER_PINS_ENABLED) v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */ else v |= MXC_H1_OC_DIS_BIT; /* OC is not used */ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET); if (flags & MXC_EHCI_ITC_NO_THRESHOLD) /* Interrupt Threshold Control:Immediate (no threshold) */ v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK; __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET); break; } error: iounmap(usb_base); return ret; } #endif printk(KERN_WARNING "%s() unable to setup USBCONTROL for this CPU\n", __func__); return -EINVAL; }
static int __devinit spi_imx_probe(struct platform_device *pdev) { struct spi_imx_master *mxc_platform_info; struct spi_master *master; struct spi_imx_data *spi_imx; struct resource *res; int i, ret; mxc_platform_info = dev_get_platdata(&pdev->dev); if (!mxc_platform_info) { dev_err(&pdev->dev, "can't get the platform data\n"); return -EINVAL; } master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data)); if (!master) return -ENOMEM; platform_set_drvdata(pdev, master); master->bus_num = pdev->id; master->num_chipselect = mxc_platform_info->num_chipselect; spi_imx = spi_master_get_devdata(master); spi_imx->bitbang.master = spi_master_get(master); spi_imx->chipselect = mxc_platform_info->chipselect; for (i = 0; i < master->num_chipselect; i++) { if (spi_imx->chipselect[i] < 0) continue; ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); if (ret) { while (i > 0) { i--; if (spi_imx->chipselect[i] >= 0) gpio_free(spi_imx->chipselect[i]); } dev_err(&pdev->dev, "can't get cs gpios\n"); goto out_master_put; } } spi_imx->bitbang.chipselect = spi_imx_chipselect; spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; spi_imx->bitbang.txrx_bufs = spi_imx_transfer; spi_imx->bitbang.master->setup = spi_imx_setup; spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; init_completion(&spi_imx->xfer_done); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "can't get platform resource\n"); ret = -ENOMEM; goto out_gpio_free; } if (!request_mem_region(res->start, resource_size(res), pdev->name)) { dev_err(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto out_gpio_free; } spi_imx->base = ioremap(res->start, resource_size(res)); if (!spi_imx->base) { ret = -EINVAL; goto out_release_mem; } spi_imx->irq = platform_get_irq(pdev, 0); if (spi_imx->irq <= 0) { ret = -EINVAL; goto out_iounmap; } ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx); if (ret) { dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret); goto out_iounmap; } if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) { spi_imx->intctrl = mx31_intctrl; spi_imx->config = mx31_config; spi_imx->trigger = mx31_trigger; spi_imx->rx_available = mx31_rx_available; } else if (cpu_is_mx27() || cpu_is_mx21()) { spi_imx->intctrl = mx27_intctrl; spi_imx->config = mx27_config; spi_imx->trigger = mx27_trigger; spi_imx->rx_available = mx27_rx_available; } else if (cpu_is_mx1()) { spi_imx->intctrl = mx1_intctrl; spi_imx->config = mx1_config; spi_imx->trigger = mx1_trigger; spi_imx->rx_available = mx1_rx_available; } else BUG(); spi_imx->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(spi_imx->clk)) { dev_err(&pdev->dev, "unable to get clock\n"); ret = PTR_ERR(spi_imx->clk); goto out_free_irq; } clk_enable(spi_imx->clk); spi_imx->spi_clk = clk_get_rate(spi_imx->clk); if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) writel(1, spi_imx->base + MXC_RESET); /* drain receive buffer */ if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) readl(spi_imx->base + MXC_CSPIRXDATA); spi_imx->intctrl(spi_imx, 0); ret = spi_bitbang_start(&spi_imx->bitbang); if (ret) { dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); goto out_clk_put; } dev_info(&pdev->dev, "probed\n"); return ret; out_clk_put: clk_disable(spi_imx->clk); clk_put(spi_imx->clk); out_free_irq: free_irq(spi_imx->irq, spi_imx); out_iounmap: iounmap(spi_imx->base); out_release_mem: release_mem_region(res->start, resource_size(res)); out_gpio_free: for (i = 0; i < master->num_chipselect; i++) if (spi_imx->chipselect[i] >= 0) gpio_free(spi_imx->chipselect[i]); out_master_put: spi_master_put(master); kfree(master); platform_set_drvdata(pdev, NULL); return ret; }
static int __devinit spi_imx_probe(struct platform_device *pdev) { struct spi_imx_master *mxc_platform_info; struct spi_master *master; struct spi_imx_data *spi_imx; struct resource *res; int i, ret; mxc_platform_info = dev_get_platdata(&pdev->dev); if (!mxc_platform_info) { dev_err(&pdev->dev, "can't get the platform data\n"); return -EINVAL; } master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data)); if (!master) return -ENOMEM; platform_set_drvdata(pdev, master); master->bus_num = pdev->id; master->num_chipselect = mxc_platform_info->num_chipselect; spi_imx = spi_master_get_devdata(master); spi_imx->bitbang.master = spi_master_get(master); spi_imx->chipselect = mxc_platform_info->chipselect; for (i = 0; i < master->num_chipselect; i++) { if (spi_imx->chipselect[i] < 0) continue; ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); if (ret) { while (i > 0) { i--; if (spi_imx->chipselect[i] >= 0) gpio_free(spi_imx->chipselect[i]); } dev_err(&pdev->dev, "can't get cs gpios\n"); goto out_master_put; } } spi_imx->bitbang.chipselect = spi_imx_chipselect; spi_imx->bitbang.setup_transfer = spi_imx_setupxfer; spi_imx->bitbang.txrx_bufs = spi_imx_transfer; spi_imx->bitbang.master->setup = spi_imx_setup; spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; init_completion(&spi_imx->xfer_done); if (pdev->id_entry->driver_data == SPI_IMX_VER_AUTODETECT) { if (cpu_is_mx25() || cpu_is_mx35()) spi_imx->devtype_data = spi_imx_devtype_data[SPI_IMX_VER_0_7]; else if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) spi_imx->devtype_data = spi_imx_devtype_data[SPI_IMX_VER_0_4]; else if (cpu_is_mx27() || cpu_is_mx21()) spi_imx->devtype_data = spi_imx_devtype_data[SPI_IMX_VER_0_0]; else if (cpu_is_mx1()) spi_imx->devtype_data = spi_imx_devtype_data[SPI_IMX_VER_IMX1]; else BUG(); } else spi_imx->devtype_data = spi_imx_devtype_data[pdev->id_entry->driver_data]; if (!spi_imx->devtype_data.intctrl) { dev_err(&pdev->dev, "no support for this device compiled in\n"); ret = -ENODEV; goto out_gpio_free; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "can't get platform resource\n"); ret = -ENOMEM; goto out_gpio_free; } if (!request_mem_region(res->start, resource_size(res), pdev->name)) { dev_err(&pdev->dev, "request_mem_region failed\n"); ret = -EBUSY; goto out_gpio_free; } spi_imx->base = ioremap(res->start, resource_size(res)); if (!spi_imx->base) { ret = -EINVAL; goto out_release_mem; } spi_imx->irq = platform_get_irq(pdev, 0); if (spi_imx->irq <= 0) { ret = -EINVAL; goto out_iounmap; } ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx); if (ret) { dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret); goto out_iounmap; } spi_imx->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(spi_imx->clk)) { dev_err(&pdev->dev, "unable to get clock\n"); ret = PTR_ERR(spi_imx->clk); goto out_free_irq; } clk_enable(spi_imx->clk); spi_imx->spi_clk = clk_get_rate(spi_imx->clk); spi_imx->devtype_data.reset(spi_imx); spi_imx->devtype_data.intctrl(spi_imx, 0); ret = spi_bitbang_start(&spi_imx->bitbang); if (ret) { dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); goto out_clk_put; } dev_info(&pdev->dev, "probed\n"); return ret; out_clk_put: clk_disable(spi_imx->clk); clk_put(spi_imx->clk); out_free_irq: free_irq(spi_imx->irq, spi_imx); out_iounmap: iounmap(spi_imx->base); out_release_mem: release_mem_region(res->start, resource_size(res)); out_gpio_free: for (i = 0; i < master->num_chipselect; i++) if (spi_imx->chipselect[i] >= 0) gpio_free(spi_imx->chipselect[i]); out_master_put: spi_master_put(master); kfree(master); platform_set_drvdata(pdev, NULL); return ret; }